<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://open-iov.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Arthur</id>
	<title>Open-IOV - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://open-iov.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Arthur"/>
	<link rel="alternate" type="text/html" href="https://open-iov.org/index.php/Special:Contributions/Arthur"/>
	<updated>2026-06-04T00:37:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23794</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23794"/>
		<updated>2024-04-19T16:27:15Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== Driver Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia]&lt;br /&gt;
&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD] &lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23793</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23793"/>
		<updated>2024-04-19T16:16:14Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== Driver Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia]&lt;br /&gt;
&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD] &lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23792</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23792"/>
		<updated>2023-06-19T17:54:32Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;br /&gt;
#[https://openglbook.com/chapter-0-preface-what-is-opengl.html openglbook.com: What is OpenGL?]&lt;br /&gt;
#[https://yewtu.be/watch?v=haes4_Xnc5Q &amp;lt;nowiki&amp;gt;[2020] Getting pixels on screen: introduction to Kernel Mode Setting (KMS) by Simon Ser&amp;lt;/nowiki&amp;gt;] - [https://fs.emersion.fr/protected/presentations/present.html?src=kms-foss-north/index.md#1 slides]&lt;br /&gt;
#[https://sdic.sjtu.edu.cn/wp-content/uploads/2019/12/Mediated-Pass-Through-MPT-NVIDIA-vGPU.pptx Dynamic Mediation for Live Migration VFIO-PCI]&lt;br /&gt;
#[https://lwn.net/Articles/746127/ DRM Management Via CGroups]&lt;br /&gt;
#[https://lwn.net/Articles/292583/ DRM: Add GEM (&amp;quot;graphics execution manager&amp;quot;) to i915 driver.]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23791</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23791"/>
		<updated>2023-06-19T17:53:55Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== Vendor Neutral ==&lt;br /&gt;
This section will detail functions in common between GPU drivers.&lt;br /&gt;
&lt;br /&gt;
Also see [https://github.com/intel/Display-Virtualization-for-Windows-OS Display Virtualization for Windows OS].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Satyeshwar Singh'''.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will deal with graphics buffer sharing for vendor neutral GPUs.&lt;br /&gt;
&lt;br /&gt;
===== Display Flow in Linux =====&lt;br /&gt;
Userspace applications provide their buffers to compositor.&lt;br /&gt;
&lt;br /&gt;
Compositor asks Mesa to create a framebuffer.&lt;br /&gt;
&lt;br /&gt;
Framebuffer is allocated through vendor driver.&lt;br /&gt;
&lt;br /&gt;
Vendor driver flips the framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== SR-IOV and Mdev =====&lt;br /&gt;
SR-IOV VFs don't have access to the display controller (only PF does).&lt;br /&gt;
&lt;br /&gt;
Known issue is displaying a VF's framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== VFs in QEMU Hypervisor (VirtIO-GPU) =====&lt;br /&gt;
SR-IOV and Mdev VFs run in QEMU Hypervisor.&lt;br /&gt;
&lt;br /&gt;
QEMU has full access to all pages in VF's address space.&lt;br /&gt;
&lt;br /&gt;
VirtIO-GPU allows for allocating buffers (not API remoting in this case).&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO allocates framebuffer via virtio-gpu.&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO asks vendor driver to import framebuffer (no specific compositor dependancy).&lt;br /&gt;
&lt;br /&gt;
===== Transport =====&lt;br /&gt;
A Scatter Gather List (SGL) of physical pages is constructed by VirtIO-GPU of VF.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side u-dma-buf ======&lt;br /&gt;
Host QEMU uses u-dma-buf driver to reconstruct a virtual memory pointer from the SGL shared by VF.&lt;br /&gt;
&lt;br /&gt;
u-dma-buf driver allocates contiguous memory blocks in kernel as DMA buffers.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side Modules ======&lt;br /&gt;
Once virtio-qemu has a DMA buffer, it shares it with the QEMU UI.&lt;br /&gt;
&lt;br /&gt;
QEMU UI has several toolkits to support like GTK, SDL, etc. with GTK. being the default.&lt;br /&gt;
&lt;br /&gt;
GTK uses EGL and passes it the DMABUF as a texture.&lt;br /&gt;
&lt;br /&gt;
===== Windows VFs =====&lt;br /&gt;
Windows OS doesn't support DMABUF capability so we can't allocate buffers from VirtIO-GPU and share them with the Windows Kernel Mode Driver (KMD).&lt;br /&gt;
&lt;br /&gt;
Windows OS is different in the way that the FB is allocated via the OS rather than the miniport driver.&lt;br /&gt;
&lt;br /&gt;
Modified version of RedHat virtio-gpu-do (short for Display Only) driver used.&lt;br /&gt;
&lt;br /&gt;
===== Windows Driver Stack =====&lt;br /&gt;
OS (DWM) allocates frame buffers and asks GPU to write to them through Miniport.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) asks the OS for the FB copy.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) passes the virtual memory address to DVServer KMD.&lt;br /&gt;
&lt;br /&gt;
===== DVServer KMD =====&lt;br /&gt;
DVServer KMD finds the SGL (Scatter Gather List) of physical pages for this virtual memory address.&lt;br /&gt;
&lt;br /&gt;
This SGL is passed via virt-queue from the VF to the host QEMU.&lt;br /&gt;
&lt;br /&gt;
===== Android VFs =====&lt;br /&gt;
Android uses Linux kernel underneath. VirtIO-GPU is present in Android's kernel.&lt;br /&gt;
&lt;br /&gt;
KMSRO patch to allocate framebuffer via VirtIO-GPU also ported over to Android.&lt;br /&gt;
&lt;br /&gt;
Need modifications in the minigbm lib of Android to connect with KMSRO part.&lt;br /&gt;
&lt;br /&gt;
Rest of stack looks identical to Linux VF/PF.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Zhi Wang''', '''Ben Widawsky''', and '''Igor Bogdanov'''.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
Aliasing PPGTT (Per Process Graphics Translation Table) refers to partially separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
Real PPGTT (Per Process Graphics Translation Table) refers to fully separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Andy Currid''', '''Neo Jia''', '''John Fanelli''', and '''Neha Joshi'''.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;br /&gt;
#[https://docs.nvidia.com/cuda/parallel-thread-execution/ Nvidia Parallel Thread Execution (PTX)]&lt;br /&gt;
#[https://blog.ffwll.ch/2013/01/i915gem-crashcourse-overview.html i915/GEM Crashcourse]&lt;br /&gt;
#[https://lwn.net/Articles/292583/ drm: Add GEM (&amp;quot;graphics execution manager&amp;quot;) to i915 driver.]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23790</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23790"/>
		<updated>2023-06-19T17:52:39Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;br /&gt;
#[https://openglbook.com/chapter-0-preface-what-is-opengl.html openglbook.com: What is OpenGL?]&lt;br /&gt;
#[https://yewtu.be/watch?v=haes4_Xnc5Q &amp;lt;nowiki&amp;gt;[2020] Getting pixels on screen: introduction to Kernel Mode Setting (KMS) by Simon Ser&amp;lt;/nowiki&amp;gt;] - [https://fs.emersion.fr/protected/presentations/present.html?src=kms-foss-north/index.md#1 slides]&lt;br /&gt;
#[https://sdic.sjtu.edu.cn/wp-content/uploads/2019/12/Mediated-Pass-Through-MPT-NVIDIA-vGPU.pptx Dynamic Mediation for Live Migration VFIO-PCI]&lt;br /&gt;
#[https://lwn.net/Articles/746127/ DRM Management Via CGroups]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23789</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23789"/>
		<updated>2023-06-19T17:51:34Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== Vendor Neutral ==&lt;br /&gt;
This section will detail functions in common between GPU drivers.&lt;br /&gt;
&lt;br /&gt;
Also see [https://github.com/intel/Display-Virtualization-for-Windows-OS Display Virtualization for Windows OS].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Satyeshwar Singh'''.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will deal with graphics buffer sharing for vendor neutral GPUs.&lt;br /&gt;
&lt;br /&gt;
===== Display Flow in Linux =====&lt;br /&gt;
Userspace applications provide their buffers to compositor.&lt;br /&gt;
&lt;br /&gt;
Compositor asks Mesa to create a framebuffer.&lt;br /&gt;
&lt;br /&gt;
Framebuffer is allocated through vendor driver.&lt;br /&gt;
&lt;br /&gt;
Vendor driver flips the framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== SR-IOV and Mdev =====&lt;br /&gt;
SR-IOV VFs don't have access to the display controller (only PF does).&lt;br /&gt;
&lt;br /&gt;
Known issue is displaying a VF's framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== VFs in QEMU Hypervisor (VirtIO-GPU) =====&lt;br /&gt;
SR-IOV and Mdev VFs run in QEMU Hypervisor.&lt;br /&gt;
&lt;br /&gt;
QEMU has full access to all pages in VF's address space.&lt;br /&gt;
&lt;br /&gt;
VirtIO-GPU allows for allocating buffers (not API remoting in this case).&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO allocates framebuffer via virtio-gpu.&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO asks vendor driver to import framebuffer (no specific compositor dependancy).&lt;br /&gt;
&lt;br /&gt;
===== Transport =====&lt;br /&gt;
A Scatter Gather List (SGL) of physical pages is constructed by VirtIO-GPU of VF.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side u-dma-buf ======&lt;br /&gt;
Host QEMU uses u-dma-buf driver to reconstruct a virtual memory pointer from the SGL shared by VF.&lt;br /&gt;
&lt;br /&gt;
u-dma-buf driver allocates contiguous memory blocks in kernel as DMA buffers.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side Modules ======&lt;br /&gt;
Once virtio-qemu has a DMA buffer, it shares it with the QEMU UI.&lt;br /&gt;
&lt;br /&gt;
QEMU UI has several toolkits to support like GTK, SDL, etc. with GTK. being the default.&lt;br /&gt;
&lt;br /&gt;
GTK uses EGL and passes it the DMABUF as a texture.&lt;br /&gt;
&lt;br /&gt;
===== Windows VFs =====&lt;br /&gt;
Windows OS doesn't support DMABUF capability so we can't allocate buffers from VirtIO-GPU and share them with the Windows Kernel Mode Driver (KMD).&lt;br /&gt;
&lt;br /&gt;
Windows OS is different in the way that the FB is allocated via the OS rather than the miniport driver.&lt;br /&gt;
&lt;br /&gt;
Modified version of RedHat virtio-gpu-do (short for Display Only) driver used.&lt;br /&gt;
&lt;br /&gt;
===== Windows Driver Stack =====&lt;br /&gt;
OS (DWM) allocates frame buffers and asks GPU to write to them through Miniport.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) asks the OS for the FB copy.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) passes the virtual memory address to DVServer KMD.&lt;br /&gt;
&lt;br /&gt;
===== DVServer KMD =====&lt;br /&gt;
DVServer KMD finds the SGL (Scatter Gather List) of physical pages for this virtual memory address.&lt;br /&gt;
&lt;br /&gt;
This SGL is passed via virt-queue from the VF to the host QEMU.&lt;br /&gt;
&lt;br /&gt;
===== Android VFs =====&lt;br /&gt;
Android uses Linux kernel underneath. VirtIO-GPU is present in Android's kernel.&lt;br /&gt;
&lt;br /&gt;
KMSRO patch to allocate framebuffer via VirtIO-GPU also ported over to Android.&lt;br /&gt;
&lt;br /&gt;
Need modifications in the minigbm lib of Android to connect with KMSRO part.&lt;br /&gt;
&lt;br /&gt;
Rest of stack looks identical to Linux VF/PF.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Zhi Wang''', '''Ben Widawsky''', and '''Igor Bogdanov'''.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
Aliasing PPGTT (Per Process Graphics Translation Table) refers to partially separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
Real PPGTT (Per Process Graphics Translation Table) refers to fully separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Andy Currid''', '''Neo Jia''', '''John Fanelli''', and '''Neha Joshi'''.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;br /&gt;
#[https://docs.nvidia.com/cuda/parallel-thread-execution/ Nvidia Parallel Thread Execution (PTX)]&lt;br /&gt;
#[https://blog.ffwll.ch/2013/01/i915gem-crashcourse-overview.html i915/GEM Crashcourse]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23788</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23788"/>
		<updated>2023-06-16T20:54:27Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* QEMU Host-Side Modules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== Vendor Neutral ==&lt;br /&gt;
This section will detail functions in common between GPU drivers.&lt;br /&gt;
&lt;br /&gt;
Also see [https://github.com/intel/Display-Virtualization-for-Windows-OS Display Virtualization for Windows OS].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Satyeshwar Singh'''.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will deal with graphics buffer sharing for vendor neutral GPUs.&lt;br /&gt;
&lt;br /&gt;
===== Display Flow in Linux =====&lt;br /&gt;
Userspace applications provide their buffers to compositor.&lt;br /&gt;
&lt;br /&gt;
Compositor asks Mesa to create a framebuffer.&lt;br /&gt;
&lt;br /&gt;
Framebuffer is allocated through vendor driver.&lt;br /&gt;
&lt;br /&gt;
Vendor driver flips the framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== SR-IOV and Mdev =====&lt;br /&gt;
SR-IOV VFs don't have access to the display controller (only PF does).&lt;br /&gt;
&lt;br /&gt;
Known issue is displaying a VF's framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== VFs in QEMU Hypervisor (VirtIO-GPU) =====&lt;br /&gt;
SR-IOV and Mdev VFs run in QEMU Hypervisor.&lt;br /&gt;
&lt;br /&gt;
QEMU has full access to all pages in VF's address space.&lt;br /&gt;
&lt;br /&gt;
VirtIO-GPU allows for allocating buffers (not API remoting in this case).&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO allocates framebuffer via virtio-gpu.&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO asks vendor driver to import framebuffer (no specific compositor dependancy).&lt;br /&gt;
&lt;br /&gt;
===== Transport =====&lt;br /&gt;
A Scatter Gather List (SGL) of physical pages is constructed by VirtIO-GPU of VF.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side u-dma-buf ======&lt;br /&gt;
Host QEMU uses u-dma-buf driver to reconstruct a virtual memory pointer from the SGL shared by VF.&lt;br /&gt;
&lt;br /&gt;
u-dma-buf driver allocates contiguous memory blocks in kernel as DMA buffers.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side Modules ======&lt;br /&gt;
Once virtio-qemu has a DMA buffer, it shares it with the QEMU UI.&lt;br /&gt;
&lt;br /&gt;
QEMU UI has several toolkits to support like GTK, SDL, etc. with GTK. being the default.&lt;br /&gt;
&lt;br /&gt;
GTK uses EGL and passes it the DMABUF as a texture.&lt;br /&gt;
&lt;br /&gt;
===== Windows VFs =====&lt;br /&gt;
Windows OS doesn't support DMABUF capability so we can't allocate buffers from VirtIO-GPU and share them with the Windows Kernel Mode Driver (KMD).&lt;br /&gt;
&lt;br /&gt;
Windows OS is different in the way that the FB is allocated via the OS rather than the miniport driver.&lt;br /&gt;
&lt;br /&gt;
Modified version of RedHat virtio-gpu-do (short for Display Only) driver used.&lt;br /&gt;
&lt;br /&gt;
===== Windows Driver Stack =====&lt;br /&gt;
OS (DWM) allocates frame buffers and asks GPU to write to them through Miniport.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) asks the OS for the FB copy.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) passes the virtual memory address to DVServer KMD.&lt;br /&gt;
&lt;br /&gt;
===== DVServer KMD =====&lt;br /&gt;
DVServer KMD finds the SGL (Scatter Gather List) of physical pages for this virtual memory address.&lt;br /&gt;
&lt;br /&gt;
This SGL is passed via virt-queue from the VF to the host QEMU.&lt;br /&gt;
&lt;br /&gt;
===== Android VFs =====&lt;br /&gt;
Android uses Linux kernel underneath. VirtIO-GPU is present in Android's kernel.&lt;br /&gt;
&lt;br /&gt;
KMSRO patch to allocate framebuffer via VirtIO-GPU also ported over to Android.&lt;br /&gt;
&lt;br /&gt;
Need modifications in the minigbm lib of Android to connect with KMSRO part.&lt;br /&gt;
&lt;br /&gt;
Rest of stack looks identical to Linux VF/PF.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Zhi Wang''', '''Ben Widawsky''', and '''Igor Bogdanov'''.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
Aliasing PPGTT (Per Process Graphics Translation Table) refers to partially separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
Real PPGTT (Per Process Graphics Translation Table) refers to fully separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Andy Currid''', '''Neo Jia''', '''John Fanelli''', and '''Neha Joshi'''.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;br /&gt;
#[https://docs.nvidia.com/cuda/parallel-thread-execution/ Nvidia Parallel Thread Execution (PTX)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23787</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23787"/>
		<updated>2023-06-16T20:54:13Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== Vendor Neutral ==&lt;br /&gt;
This section will detail functions in common between GPU drivers.&lt;br /&gt;
&lt;br /&gt;
Also see [https://github.com/intel/Display-Virtualization-for-Windows-OS Display Virtualization for Windows OS].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Satyeshwar Singh'''.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will deal with graphics buffer sharing for vendor neutral GPUs.&lt;br /&gt;
&lt;br /&gt;
===== Display Flow in Linux =====&lt;br /&gt;
Userspace applications provide their buffers to compositor.&lt;br /&gt;
&lt;br /&gt;
Compositor asks Mesa to create a framebuffer.&lt;br /&gt;
&lt;br /&gt;
Framebuffer is allocated through vendor driver.&lt;br /&gt;
&lt;br /&gt;
Vendor driver flips the framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== SR-IOV and Mdev =====&lt;br /&gt;
SR-IOV VFs don't have access to the display controller (only PF does).&lt;br /&gt;
&lt;br /&gt;
Known issue is displaying a VF's framebuffer on the screen.&lt;br /&gt;
&lt;br /&gt;
===== VFs in QEMU Hypervisor (VirtIO-GPU) =====&lt;br /&gt;
SR-IOV and Mdev VFs run in QEMU Hypervisor.&lt;br /&gt;
&lt;br /&gt;
QEMU has full access to all pages in VF's address space.&lt;br /&gt;
&lt;br /&gt;
VirtIO-GPU allows for allocating buffers (not API remoting in this case).&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO allocates framebuffer via virtio-gpu.&lt;br /&gt;
&lt;br /&gt;
Mesa's KMSRO asks vendor driver to import framebuffer (no specific compositor dependancy).&lt;br /&gt;
&lt;br /&gt;
===== Transport =====&lt;br /&gt;
A Scatter Gather List (SGL) of physical pages is constructed by VirtIO-GPU of VF.&lt;br /&gt;
&lt;br /&gt;
====== QEMU Host-Side u-dma-buf ======&lt;br /&gt;
Host QEMU uses u-dma-buf driver to reconstruct a virtual memory pointer from the SGL shared by VF.&lt;br /&gt;
&lt;br /&gt;
u-dma-buf driver allocates contiguous memory blocks in kernel as DMA buffers.&lt;br /&gt;
&lt;br /&gt;
====== '''QEMU Host-Side Modules''' ======&lt;br /&gt;
Once virtio-qemu has a DMA buffer, it shares it with the QEMU UI.&lt;br /&gt;
&lt;br /&gt;
QEMU UI has several toolkits to support like GTK, SDL, etc. with GTK. being the default.&lt;br /&gt;
&lt;br /&gt;
GTK uses EGL and passes it the DMABUF as a texture.&lt;br /&gt;
&lt;br /&gt;
===== Windows VFs =====&lt;br /&gt;
Windows OS doesn't support DMABUF capability so we can't allocate buffers from VirtIO-GPU and share them with the Windows Kernel Mode Driver (KMD).&lt;br /&gt;
&lt;br /&gt;
Windows OS is different in the way that the FB is allocated via the OS rather than the miniport driver.&lt;br /&gt;
&lt;br /&gt;
Modified version of RedHat virtio-gpu-do (short for Display Only) driver used.&lt;br /&gt;
&lt;br /&gt;
===== Windows Driver Stack =====&lt;br /&gt;
OS (DWM) allocates frame buffers and asks GPU to write to them through Miniport.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) asks the OS for the FB copy.&lt;br /&gt;
&lt;br /&gt;
DVServer UMD (IDD) passes the virtual memory address to DVServer KMD.&lt;br /&gt;
&lt;br /&gt;
===== DVServer KMD =====&lt;br /&gt;
DVServer KMD finds the SGL (Scatter Gather List) of physical pages for this virtual memory address.&lt;br /&gt;
&lt;br /&gt;
This SGL is passed via virt-queue from the VF to the host QEMU.&lt;br /&gt;
&lt;br /&gt;
===== Android VFs =====&lt;br /&gt;
Android uses Linux kernel underneath. VirtIO-GPU is present in Android's kernel.&lt;br /&gt;
&lt;br /&gt;
KMSRO patch to allocate framebuffer via VirtIO-GPU also ported over to Android.&lt;br /&gt;
&lt;br /&gt;
Need modifications in the minigbm lib of Android to connect with KMSRO part.&lt;br /&gt;
&lt;br /&gt;
Rest of stack looks identical to Linux VF/PF.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Zhi Wang''', '''Ben Widawsky''', and '''Igor Bogdanov'''.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
Aliasing PPGTT (Per Process Graphics Translation Table) refers to partially separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
Real PPGTT (Per Process Graphics Translation Table) refers to fully separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions to documentation and open source by '''Andy Currid''', '''Neo Jia''', '''John Fanelli''', and '''Neha Joshi'''.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;br /&gt;
#[https://docs.nvidia.com/cuda/parallel-thread-execution/ Nvidia Parallel Thread Execution (PTX)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23786</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23786"/>
		<updated>2023-06-13T14:58:30Z</updated>

		<summary type="html">&lt;p&gt;Arthur: Updated Nvidia VGX vGPU version to 15.2 in GPU SBOM.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Filesize&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|in-kernel&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
|Mediated Core (mdev.ko)&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|OSS&lt;br /&gt;
|0.044 MB&lt;br /&gt;
|[https://docs.kernel.org/driver-api/vfio-mediated-device.html kernel.org]&lt;br /&gt;
|2016.xx.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU]&lt;br /&gt;
|The Mediated Core driver provides a common interface for mediated device management that can be used by drivers of different devices. It is an IOMMU/device-agnostic framework for exposing direct device access to user space in a secure, IOMMU-protected environment (based on VFIO).&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|0.084 MB&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|in-kernel&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GuC GuC]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GSP GSP]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on [https://lwn.net/Articles/637658/ LibOS] containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.2]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
|0.108 MB&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|0.132 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidia-vgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|3.1 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr].&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-vfio.ko&lt;br /&gt;
|Driver&lt;br /&gt;
|0.108 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23785</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23785"/>
		<updated>2023-06-12T17:02:36Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;br /&gt;
#[https://openglbook.com/chapter-0-preface-what-is-opengl.html openglbook.com: What is OpenGL?]&lt;br /&gt;
#[https://yewtu.be/watch?v=haes4_Xnc5Q &amp;lt;nowiki&amp;gt;[2020] Getting pixels on screen: introduction to Kernel Mode Setting (KMS) by Simon Ser&amp;lt;/nowiki&amp;gt;] - [https://fs.emersion.fr/protected/presentations/present.html?src=kms-foss-north/index.md#1 slides]&lt;br /&gt;
#[https://sdic.sjtu.edu.cn/wp-content/uploads/2019/12/Mediated-Pass-Through-MPT-NVIDIA-vGPU.pptx Dynamic Mediation for Live Migration VFIO-PCI]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23784</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23784"/>
		<updated>2023-05-25T20:33:37Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
Aliasing PPGTT (Per Process Graphics Translation Table) refers to partially separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
Real PPGTT (Per Process Graphics Translation Table) refers to fully separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;br /&gt;
#[https://docs.nvidia.com/cuda/parallel-thread-execution/ Nvidia Parallel Thread Execution (PTX)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23783</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23783"/>
		<updated>2023-05-22T21:20:20Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;br /&gt;
#[https://openglbook.com/chapter-0-preface-what-is-opengl.html openglbook.com: What is OpenGL?]&lt;br /&gt;
#[https://yewtu.be/watch?v=haes4_Xnc5Q &amp;lt;nowiki&amp;gt;[2020] Getting pixels on screen: introduction to Kernel Mode Setting (KMS) by Simon Ser&amp;lt;/nowiki&amp;gt;] - [https://fs.emersion.fr/protected/presentations/present.html?src=kms-foss-north/index.md#1 slides]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23782</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23782"/>
		<updated>2023-05-22T16:28:00Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;br /&gt;
#[https://openglbook.com/chapter-0-preface-what-is-opengl.html openglbook.com: What is OpenGL?]&lt;br /&gt;
#[https://yewtu.be/watch?v=haes4_Xnc5Q &amp;lt;nowiki&amp;gt;[2020] Getting pixels on screen: introduction to Kernel Mode Setting (KMS) by Simon Ser&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23781</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23781"/>
		<updated>2023-05-05T20:54:27Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;br /&gt;
#[https://openglbook.com/chapter-0-preface-what-is-opengl.html openglbook.com: What is OpenGL?]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23780</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23780"/>
		<updated>2023-05-02T20:54:52Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* GVM Integration Documents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== Driver Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia]&lt;br /&gt;
&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD] &lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Firmware&amp;diff=23779</id>
		<title>GPU Firmware</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Firmware&amp;diff=23779"/>
		<updated>2023-04-09T17:13:39Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Firmware Images */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
GPUs have become highly complex systems containing a number of different embedded controllers. This page will attempt to document embedded GPU firmware and support for IO virtualization through various firmware functions.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Intel ==&lt;br /&gt;
&lt;br /&gt;
=== Firmware Images ===&lt;br /&gt;
This section will cover firmware images used in Intel GPUs.[[File:Screen Shot 2022-11-18 at 4.14.32 PM.png|alt=Figure 1: The FSP Binary Layout from Intel® Firmware Support Package External Architecture Specification.|thumb|Figure 1: The FSP Binary Layout from Intel® Firmware Support Package External Architecture Specification. [https://cdrdv2.intel.com/v1/dl/getContent/736809 Source]]]&lt;br /&gt;
&lt;br /&gt;
==== Intel Firmware Support Package (FSP) ====&lt;br /&gt;
Much like CPUs Intel's GPUs also contain a Firmware Support Package (FSP).&lt;br /&gt;
&lt;br /&gt;
The Coreboot project provides public domain information on the FSP [https://doc.coreboot.org/soc/intel/fsp/index.html here].&lt;br /&gt;
&lt;br /&gt;
===== FSP Configuration =====&lt;br /&gt;
In the context of GPUs the FSP configures several functions of the device.&lt;br /&gt;
&lt;br /&gt;
Those functions are as follows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+GPU Firmware Support Package&lt;br /&gt;
!FSP Parameter&lt;br /&gt;
!Possible Values&lt;br /&gt;
|-&lt;br /&gt;
|GFSP Status&lt;br /&gt;
|0x00&lt;br /&gt;
|-&lt;br /&gt;
|FIVR SSC Value&lt;br /&gt;
|*.*%&lt;br /&gt;
|-&lt;br /&gt;
|FIVR RFI Value&lt;br /&gt;
|*.*MHz&lt;br /&gt;
|-&lt;br /&gt;
|GT Subsystem Vendor ID&lt;br /&gt;
|0x8086&lt;br /&gt;
|-&lt;br /&gt;
|GT Subsystem Device ID&lt;br /&gt;
|0x**&lt;br /&gt;
|-&lt;br /&gt;
|HDA Subsystem Vendor ID&lt;br /&gt;
|0x0000&lt;br /&gt;
|-&lt;br /&gt;
|HDA Subsystem Device ID&lt;br /&gt;
|0x0000&lt;br /&gt;
|-&lt;br /&gt;
|P2SB Enable&lt;br /&gt;
|Yes/No&lt;br /&gt;
|-&lt;br /&gt;
|LMEBAR&lt;br /&gt;
|Max&lt;br /&gt;
|-&lt;br /&gt;
|GTMMADDR Prefetch Capability&lt;br /&gt;
|Prefetch Enabled&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/Merged_Drivers Display Present]&lt;br /&gt;
|Enabled/Disabled&lt;br /&gt;
|-&lt;br /&gt;
|I2C For Third Party Devices&lt;br /&gt;
|Enabled/Disabled&lt;br /&gt;
|-&lt;br /&gt;
|I2C Device Address 1&lt;br /&gt;
|0x0000&lt;br /&gt;
|-&lt;br /&gt;
|I2C Device Address 2&lt;br /&gt;
|0x0000&lt;br /&gt;
|-&lt;br /&gt;
|I2C Bus Speed&lt;br /&gt;
|Standard mode (0 to 100Kbps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Editing FSP Configuration ======&lt;br /&gt;
The FSP configuration editor can be downloaded [https://github.com/tianocore/edk2/tree/master/IntelFsp2Pkg/Tools/ConfigEditor here] and it's user manual is available [https://github.com/tianocore/edk2/blob/master/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md here].&lt;br /&gt;
&lt;br /&gt;
===== FSP Binary Format =====&lt;br /&gt;
The FSP's binary layout is detailed within the [https://cdrdv2.intel.com/v1/dl/getContent/736809 Intel® FSP External Architecture Specification v2.4] on page 14.&lt;br /&gt;
&lt;br /&gt;
==== Known Firmware Package Variations ====&lt;br /&gt;
Some firmware packages may include an **End of Manufacturing Flash Protection Mode** status of Protected or Unprotected.&lt;br /&gt;
[[File:Figure 2- Firmware status information for an Intel DG2 device..png|alt=Figure 2: Firmware status information for an Intel DG2 device.|thumb|Figure 2: Firmware status information for an Intel DG2 device.]]&lt;br /&gt;
Similar [https://eclypsium.com/2022/09/19/firmware-security-realizations-part-3-spi-write-protections/ SPI Write Protection] functionality is made available through Intel CPUs under [[wikipedia:System_Management_Mode|System Management Mode (SMM)]].&lt;br /&gt;
&lt;br /&gt;
=== Embedded Controllers ===&lt;br /&gt;
This section will cover firmware images as they apply to various embedded controllers within the Intel GPU.&lt;br /&gt;
&lt;br /&gt;
==== GuC ====&lt;br /&gt;
The Graphics micro (µ) Controller (GuC) is an embedded controller contained within Intel's embedded and discrete graphics (DG*) series GPUs.&lt;br /&gt;
&lt;br /&gt;
===== Hardware Architecture =====&lt;br /&gt;
&lt;br /&gt;
''The following section is supported by [https://igor-blue.github.io/2021/02/10/graphics-part1.html igor-blue.github.io] (see reference [https://open-iov.org/index.php/GPU_Firmware#References_(Talks_&amp;amp;_Reading_Material) 1], [https://open-iov.org/index.php/GPU_Firmware#References_(Talks_&amp;amp;_Reading_Material) 2]):''&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;The GuC - an embedded [https://www.wikiwand.com/en/I486 i486] core that supports graphics scheduling, power management and firmware attestation.&amp;quot;''&lt;br /&gt;
===== Software Architecture =====&lt;br /&gt;
&lt;br /&gt;
''The following section is supported by [https://igor-blue.github.io/2021/02/10/graphics-part1.html igor-blue.github.io] (see reference [https://open-iov.org/index.php/GPU_Firmware#References_(Talks_&amp;amp;_Reading_Material) 1], [https://open-iov.org/index.php/GPU_Firmware#References_(Talks_&amp;amp;_Reading_Material) 2]):''&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;The μOS kernel runs in 32-bit protected mode, with no paging and old-style segments model (CS, DS, etc’). All code run in ring0. The OS handles HW/SW exceptions and crashes, and supplies debugging and logging services.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
''&amp;quot;It runs a single process - which initializes the system and then waits for interrupts/events in a loop.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
====== GuC Blob Checksum &amp;amp; Code Signing ======&lt;br /&gt;
''&amp;quot;The bootrom verifies the firmware with a digital signature using a SHA256 hash + PKCSv2.1 RSA signature, and if the test passes copies it to SRAM and starts executing.&amp;quot;''&lt;br /&gt;
== Nvidia ==&lt;br /&gt;
&lt;br /&gt;
=== Firmware Images ===&lt;br /&gt;
This section will cover firmware images used in Nvidia GPUs.&lt;br /&gt;
&lt;br /&gt;
=== Embedded Controllers ===&lt;br /&gt;
This section will cover firmware images as they apply to various embedded controllers within the Nvidia GPU.&lt;br /&gt;
&lt;br /&gt;
==== Falcon / NV-RISCV ====&lt;br /&gt;
The Fast Logic CONtroller (Falcon) and Nvidia RISC-V ([https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf NV-RISCV]) processors run the NvOS.&lt;br /&gt;
&lt;br /&gt;
==== GSP ====&lt;br /&gt;
The GPU System Processor (GSP) is an embedded controller used for offload of the RM Core.&lt;br /&gt;
&lt;br /&gt;
The GSP runs [https://lwn.net/Articles/637658/ Library Operating System (LibOS)].&lt;br /&gt;
&lt;br /&gt;
===== GSP Initialization &amp;amp; Offload =====&lt;br /&gt;
The [https://open-iov.org/index.php/GPU_Driver_Internals#Initialization_3 GSP is initialized multiple times] during the system's bring up and runtime.&lt;br /&gt;
&lt;br /&gt;
GSP offload may occur during:&lt;br /&gt;
&lt;br /&gt;
* Hardware bring up when a cached version of the RM Core is loaded from SPI flash &lt;br /&gt;
&lt;br /&gt;
* During host driver bring up when the RM Core is offloaded by the [https://open-iov.org/index.php/OpenRM OpenRM driver].&lt;br /&gt;
* During guest driver bring up when the RM Core is offloaded.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Possible GSP Offloads&lt;br /&gt;
!Load Source&lt;br /&gt;
!Payload&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|[https://wiki.segger.com/SPI_Flash SPI Flash]&lt;br /&gt;
|Cached RM Core&lt;br /&gt;
|Used as a fallback in case of no rm offload.&lt;br /&gt;
|-&lt;br /&gt;
|OpenRM&lt;br /&gt;
|RM Core&lt;br /&gt;
|This is the RM Core which was traditionally contained in the proprietary RM driver.&lt;br /&gt;
|-&lt;br /&gt;
|VGX Guest&lt;br /&gt;
|Guest RM Core&lt;br /&gt;
|Future OpenRM guests may accomplish RM offload via GSP stubs (controlled via [https://github.com/NVIDIA/open-gpu-kernel-modules/blob/758b4ee8189c5198504cb1c3c5bc29027a9118a3/src/common/sdk/nvidia/inc/ctrl/ctrla081.h#L102 gspHeapSize]?).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== CMU ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== AMD ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://igor-blue.github.io/2021/02/10/graphics-part1.html Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
# [https://igor-blue.github.io/2021/02/24/graphics-part2.html Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://eclypsium.com/2022/09/19/firmware-security-realizations-part-3-spi-write-protections/ Firmware Security Realizations Part 3: SPI Write Protections]&lt;br /&gt;
#[https://www.intel.com/content/www/us/en/intelligent-systems/intel-firmware-support-package/fsp-firmware-solutions-iot-video.html Intel® FSP: Firmware Solutions for the Internet of Things]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23778</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23778"/>
		<updated>2023-04-05T23:31:35Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html docs.kernel.org: DRM Memory Management]&lt;br /&gt;
#[https://docs.kernel.org/PCI/index.html docs.kernel.org: PCI Bus Subsystem]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23777</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23777"/>
		<updated>2023-04-05T23:29:44Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Translation Tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
Aliasing PPGTT (Per Process Graphics Translation Table) refers to partially separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
Real PPGTT (Per Process Graphics Translation Table) refers to fully separated GPU resources (process context).&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23776</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23776"/>
		<updated>2023-04-05T23:27:44Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Lifecycle of a Triangle - Nvidia's logical pipeline]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23775</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23775"/>
		<updated>2023-04-05T21:21:07Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Host usermode (nvidia-vgpu-mgr / libnvidiavgpu.so) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidia-vgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr, and it's library libnvidia-vgpu.so) are executed to schedule VM-exits described below.&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP.&lt;br /&gt;
&lt;br /&gt;
This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23774</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23774"/>
		<updated>2023-04-05T17:37:00Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Filesize&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|in-kernel&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
|Mediated Core (mdev.ko)&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|OSS&lt;br /&gt;
|0.044 MB&lt;br /&gt;
|[https://docs.kernel.org/driver-api/vfio-mediated-device.html kernel.org]&lt;br /&gt;
|2016.xx.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU]&lt;br /&gt;
|The Mediated Core driver provides a common interface for mediated device management that can be used by drivers of different devices. It is an IOMMU/device-agnostic framework for exposing direct device access to user space in a secure, IOMMU-protected environment (based on VFIO).&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|0.084 MB&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|in-kernel&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GuC GuC]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GSP GSP]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on [https://lwn.net/Articles/637658/ LibOS] containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
|0.108 MB&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|0.132 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidia-vgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|3.1 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr].&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-vfio.ko&lt;br /&gt;
|Driver&lt;br /&gt;
|0.108 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23773</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23773"/>
		<updated>2023-04-05T17:32:51Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Filesize&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
|Mediated Core (mdev.ko)&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|OSS&lt;br /&gt;
|0.044 MB&lt;br /&gt;
|[https://docs.kernel.org/driver-api/vfio-mediated-device.html kernel.org]&lt;br /&gt;
|2016.xx.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU]&lt;br /&gt;
|The Mediated Core driver provides a common interface for mediated device management that can be used by drivers of different devices. It is an IOMMU/device-agnostic framework for exposing direct device access to user space in a secure, IOMMU-protected environment (based on VFIO).&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|0.084 MB&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GuC GuC]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GSP GSP]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on [https://lwn.net/Articles/637658/ LibOS] containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
|0.108 MB&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|0.132 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidia-vgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|3.1 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr].&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-vfio.ko&lt;br /&gt;
|Driver&lt;br /&gt;
|0.108 MB&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23772</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23772"/>
		<updated>2023-04-05T17:15:57Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
|RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GuC GuC]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GSP GSP]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on [https://lwn.net/Articles/637658/ LibOS] containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidiavgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr].&lt;br /&gt;
|-&lt;br /&gt;
|nvidia_vgpu_vfio&lt;br /&gt;
|Driver&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23771</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23771"/>
		<updated>2023-04-05T17:14:51Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
|RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GuC GuC]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for [https://open-iov.org/index.php/GPU_Firmware#GSP GSP]-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on [https://lwn.net/Articles/637658/ LibOS] containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidiavgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with nvidia-vgpu-mgr.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia_vgpu_vfio&lt;br /&gt;
|Driver&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23770</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23770"/>
		<updated>2023-04-05T17:12:40Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
|RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for GuC-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for GSP-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on LibOS containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the [https://open-iov.org/index.php/GPU_Driver_Internals#nvidia-vgpu-mgr nvidia-vgpu-mgr] process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidiavgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with nvidia-vgpu-mgr.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia_vgpu_vfio&lt;br /&gt;
|Driver&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23769</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23769"/>
		<updated>2023-04-05T17:09:07Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidiavgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr) and a library (libnvidiavgpu.so).&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP. This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23768</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23768"/>
		<updated>2023-04-05T17:08:46Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* RM Core */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors. Under OpenRM the RM Core runs within the GPU System Processor (GSP micro-controller) while in pre-open source versions of the Resource Manager the RM Core ran within the nvidia.ko kernel module&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidiavgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr) and a library (libnvidiavgpu.so).&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP. This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the RM Core.&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23767</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23767"/>
		<updated>2023-04-05T17:05:38Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* nvidia-vgpu-mgr */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidiavgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr) and a library (libnvidiavgpu.so).&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
This daemon process interacts with the libnvidia-vgpu.so, nvidia.ko, and nvidia-vgpu-vfio.ko components. &lt;br /&gt;
&lt;br /&gt;
This process and the libnvidia-vgpu.so contain, and execute the VMIOP. This process (and the VMIOP) schedules RPCs sent by the guest, receives VFIO BAR-exits, and relays requests to allocate, deallocate, pin, unpin, map, unmap to the RM Core.&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23766</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23766"/>
		<updated>2023-03-30T19:01:28Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== GVM Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia]&lt;br /&gt;
&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD] &lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Main_Page&amp;diff=23765</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Main_Page&amp;diff=23765"/>
		<updated>2023-03-30T18:25:59Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the '''Open-IOV Project''' wiki.&lt;br /&gt;
&lt;br /&gt;
== [[Articles]] ==&lt;br /&gt;
'''Visit the [[Articles|Articles page]] for an overview of this wiki's contents.'''&lt;br /&gt;
&lt;br /&gt;
New and existing projects related to the following topics are welcome:&lt;br /&gt;
&lt;br /&gt;
* '''GPU &amp;amp; IO Virtualization (VFIO / SR-IOV / SIOV / Mdev)'''&lt;br /&gt;
* '''GPU &amp;amp; IO Device Drivers'''&lt;br /&gt;
*'''Hypervisor Development'''&lt;br /&gt;
*'''Virtualization Tools'''&lt;br /&gt;
'''Signups are open''' to the public and '''anyone can contribute'''.&lt;br /&gt;
&lt;br /&gt;
== Community ==&lt;br /&gt;
'''Discord:''' https://discord.gg/Rb9K9DYxKK&lt;br /&gt;
&lt;br /&gt;
'''IRC:''' #gvm &amp;amp; #gvm-devel on oftc.net&lt;br /&gt;
&lt;br /&gt;
== Contributing to Open-IOV.org ==&lt;br /&gt;
Due to spam account creation is temporarily disabled through the Open-IOV website.&lt;br /&gt;
&lt;br /&gt;
Contact Open-IOV moderators in the community '''#Documentation''' channel to have your account allowlisted until unmoderated signups re-open.&lt;br /&gt;
&lt;br /&gt;
== Creating an Article ==&lt;br /&gt;
If you'd like to start a new article or contribute to an existing one simply create an account then visit a URL containing the article title you'd like to create or edit and click the &amp;quot;Edit&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
https://open-iov.org/index.php/your-article-title-here&lt;br /&gt;
&lt;br /&gt;
New articles should be linked on the [[Articles|Articles page]] so people can find them.&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23764</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23764"/>
		<updated>2023-03-28T19:50:00Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://docs.kernel.org/gpu/drm-mm.html Kernel.org: DRM Memory Management]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Glossary&amp;diff=23763</id>
		<title>Glossary</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Glossary&amp;diff=23763"/>
		<updated>2023-03-27T19:24:26Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Virtual GPU (vGPU) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
This article will attempt to provide a glossary of common terms that are either related to/or often used in connection with virtualization for those who may need more context.&lt;br /&gt;
&lt;br /&gt;
If you have suggestions on how to improve the glossary you can [https://openmdev.io/index.php/Main_Page#Getting_Started_Contributing_to_OpenMdev.io '''contribute'''] or join our [https://discord.gg/Rb9K9DYxKK '''community discussion thread'''] to make suggestions.&lt;br /&gt;
&lt;br /&gt;
=== VFIO ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Kernel.org defines VFIO or Virtual Function Input Output as '''&amp;quot;an IOMMU/device agnostic framework for exposing direct device access to userspace, in a secure, IOMMU protected environment.&amp;quot; [https://www.kernel.org/doc/Documentation/vfio.txt &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:VFIO Diagram.png|thumb|A diagram depicting direct VFIO passthrough of a GPU adapter.]]&lt;br /&gt;
&lt;br /&gt;
=== Mdev ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Kernel.org defines Virtual Function I/O (VFIO) Mediated devices as: '''&amp;quot;an IOMMU/device-agnostic framework for exposing direct device access to user space in a secure, IOMMU-protected environment... mediated core driver provides a common interface for mediated device management that can be used by drivers of different devices.&amp;quot; [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:VFIO-Mdev Diagram.png|thumb|A diagram depicting VFIO Mediated Device interacting with two vGPU guests.]]&lt;br /&gt;
&lt;br /&gt;
=== Virtual CPU (vCPU) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;A Virtual CPU (vCPU) is a CPU which has been virtualized to represent a percentage of the total hardware resource via preemptive scheduling.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Virtual GPU (vGPU) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;A Virtual GPU (vGPU) is a GPU which has been virtualized to represent a percentage of the total hardware resource via preemptive scheduling or thread pinning (to [https://www.intel.com/content/www/us/en/docs/oneapi/optimization-guide-gpu/2023-0/intel-iris-xe-gpu-architecture.html EUs], or [https://www.nvidia.com/content/PDF/nvidia-ampere-ga-102-gpu-architecture-whitepaper-v2.pdf SMs]) and/or a partition of the device's Video Random Access Memory (VRAM).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
=== IVSHMEM ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;According to QEMU's GitHub repo: '''&amp;quot;The Inter-VM shared memory device (ivshmem) is designed to share a memory region between multiple QEMU processes running different guests and the host.  In order for all guests to be able to pick up the shared memory area, it is modeled by QEMU as a PCI device exposing said memory to the guest as a PCI BAR.&amp;quot;''' '''[https://github.com/qemu/qemu/blob/master/docs/specs/ivshmem-spec.txt &amp;lt;nowiki&amp;gt;[3]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:IVSHMEM.png|thumb|A diagram depicting an inter-vm shared memory device being used by two separate virtual machines.]]&lt;br /&gt;
&lt;br /&gt;
=== KVMFR (Looking Glass) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;looking-glass.io defines Looking Glass as: '''&amp;quot;an open source application that allows the use of a KVM (Kernel-based Virtual Machine) configured for VGA PCI Pass-through without an attached physical monitor, keyboard or mouse.&amp;quot;''' '''[https://looking-glass.io/ &amp;lt;nowiki&amp;gt;[4]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:KVMFR Looking Glass.png|thumb|A image posted by Gnif (Creator of the Looking Glass project) to a changelog thread on the Level1techs forum - an active community of VFIO users. ]]&lt;br /&gt;
&lt;br /&gt;
=== NUMA Node ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Infogalactic defines NUMA as: '''&amp;quot;''Non-uniform memory access (NUMA) is a'' computer memory design used in multiprocessing, where the memory access time depends on the memory location relative to the processor. Under NUMA, a processor can access its own local memory faster than non-local memory (memory local to another processor or memory shared between processors).&amp;quot; [https://infogalactic.com/info/Non-uniform_memory_access &amp;lt;nowiki&amp;gt;[5]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:NUMA Node.png|thumb|A diagram depicting Non-Uniform Memory Access (NUMA) nodes.]]&lt;br /&gt;
&lt;br /&gt;
=== Application Binary Interface (ABI) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Infogalactic defines an ABI as '''&amp;quot;the interface between two program modules, one of which is often a library or operating system, at the level of machine code.&amp;quot;''' '''[https://infogalactic.com/info/Application_binary_interface &amp;lt;nowiki&amp;gt;[6]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:Application Binary Interface (ABI).png|thumb|A diagram contrasting API and ABI as well as their respective roles in software compatibility.]]&lt;br /&gt;
&lt;br /&gt;
=== SR-IOV ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;docs.microsoft.com defines SR-IOV as '''&amp;quot;The single root I/O virtualization (SR-IOV) interface is an extension to the PCI Express (PCIe) specification. SR-IOV allows a device, such as a network adapter, to separate access to its resources among various PCIe hardware functions.&amp;quot; [https://archive.is/FcDoK &amp;lt;nowiki&amp;gt;[7]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:SR-IOV.png|thumb|A diagram depicting host and guest interactions in a Single Root I/O Virtualization environment.]]&lt;br /&gt;
&lt;br /&gt;
=== GVT-g ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;wiki.archlinux.org defines Intel GVT-g as '''&amp;quot;a technology that provides mediated device passthrough for Intel GPUs (Broadwell and newer). It can be used to virtualize the GPU for multiple guest virtual machines, effectively providing near-native graphics performance in the virtual machine and still letting your host use the virtualized GPU normally.&amp;quot; [https://wiki.archlinux.org/title/Intel_GVT-g &amp;lt;nowiki&amp;gt;[8]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[File:SR-IOV-Diagram.png|thumb|A diagram of Intel's GVT-g (Graphics Virtualization Technology g).]]&lt;br /&gt;
&lt;br /&gt;
=== VirGL ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;[[File:Virgl.png|thumb|A diagram depicting GPU instruction redirects to a single host graphics driver.]]lwn.net defines Virgl as: '''&amp;quot;a way for guests running in a virtual machine (VM) to access the host GPU using OpenGL and other APIs... The virgl stack consists of an application running in the guest that sends OpenGL to the Mesa virgl driver, which uses the virtio-gpu driver in the guest kernel to communicate with QEMU on the host.&amp;quot;''' '''[https://lwn.net/Articles/767970/ &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]'''&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23762</id>
		<title>Virtual I/O Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Virtual_I/O_Internals&amp;diff=23762"/>
		<updated>2023-03-27T19:08:34Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Instruction Execution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following document details the internals of a '''VFIO (Virtual Function I/O)''' driven '''Shared''' '''I/O Device.'''&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This article places emphasis on the '''Virtual GPU (vGPU)''' use case however these concepts apply generically to virtualization of I/O devices (TPUs, NICs, storage peripherals, ect..).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Comparison of Assistance Modes&lt;br /&gt;
!Mdev Mode&lt;br /&gt;
!SR-IOV Mode&lt;br /&gt;
!SIOV Mode&lt;br /&gt;
|-&lt;br /&gt;
|No hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|Hardware assistance needed.&lt;br /&gt;
|-&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|Host ignorance of guest workload.&lt;br /&gt;
|Host requires insight about guest workload.&lt;br /&gt;
|-&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|No guest driver error reporting.&lt;br /&gt;
|Error reporting.&lt;br /&gt;
|-&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|Basic dynamic monitoring.&lt;br /&gt;
|In depth dynamic monitoring.&lt;br /&gt;
|-&lt;br /&gt;
|Software defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|Firmware defined MMU guest separation.&lt;br /&gt;
|-&lt;br /&gt;
|Requires deferred instructions to be supported by host software (support libraries).&lt;br /&gt;
|Guest is ignorant of host supported software such as support libraries.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts. &lt;br /&gt;
|Routing interrupts.&lt;br /&gt;
|-&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|Device reset.&lt;br /&gt;
|-&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|Enable/Disable device.&lt;br /&gt;
|-&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|Support for multiple scheduling techniques.&lt;br /&gt;
|-&lt;br /&gt;
|Single PCI requester ID.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|Multiple PCI requester IDs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== All Modes ==&lt;br /&gt;
This section will cover concepts which apply both to [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode], [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] &amp;amp; [https://open-iov.org/index.php/Mediated_Device_Internals#SIOV_Mode SIOV Mode].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Alex Williamson.&lt;br /&gt;
&lt;br /&gt;
See references 2, 14, &amp;amp; 22 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Binding VFIO devices===&lt;br /&gt;
[[File:Vfio-pci driver bindings.png|thumb|'''Figure 1:''' VFIO group nodes are unit of ownership that VFIO uses. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:IOCTL set VFIO container.png|thumb|'''Figure 2:''' IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER) places the VFIO Group inside the VFIO Container. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO IOMMU MAP-UNMAP DMA.png|thumb|'''Figure 3:''' Using interrupts IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP), IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP) to map memory and pin pages. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
[[File:Ioctl-VFIO GROUP GET FD.png|thumb|'''Figure 4:''' Using interrupt IOCTL(GROUP2, VFIO_GROUP_GET_FD, &amp;quot;0000:01:00.0&amp;quot;) to obtain the VFIO Group file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 1:''' Binding devices to the vfio-pci driver results in VFIO group nodes.&lt;br /&gt;
&lt;br /&gt;
Opening the file &amp;quot;/dev/vfio/vfio&amp;quot; creates a VFIO Container.&lt;br /&gt;
&lt;br /&gt;
'''Figure 2:''' The interrupt routine '''&amp;lt;code&amp;gt;IOCTL(GROUP, VFIO_GROUP_SET_CONTAINER, &amp;amp;CONTAINER)&amp;lt;/code&amp;gt;''' places the VFIO group inside the VFIO container.&lt;br /&gt;
&lt;br /&gt;
===Programming the IOMMU===&lt;br /&gt;
When this has been done '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)&amp;lt;/code&amp;gt;''' can then be used to set an IOMMU type for the container which places it in a user interactable state. &lt;br /&gt;
&lt;br /&gt;
Once this IOMMU type  state has been set and the VFIO container has been made interactable additional VFIO groups may be added to the container without requiring that the group's IOMMU type be set again as newly added groups automatically inherit the container's IOMMU context.&lt;br /&gt;
&lt;br /&gt;
===VFIO Memory Mapped IO===&lt;br /&gt;
'''Figure 3:''' Once the VFIO Groups have been placed inside the VFIO container and the IOMMU type has been set the user may then map and unmap which will automatically inserts Memory Mapped IO (MMIO) entries into the IOMMU as well as pin/unpin pages as necessary. This can be accomplished using '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_MAP_DMA, &amp;amp;MAP)&amp;lt;/code&amp;gt;''' for map/pin and '''&amp;lt;code&amp;gt;IOCTL(CONTAINER, VFIO_IOMMU_UNMAP_DMA, &amp;amp;UNMAP)&amp;lt;/code&amp;gt;''' for unmap/unpin.&lt;br /&gt;
&lt;br /&gt;
=== Getting the VFIO Group File Descriptor ===&lt;br /&gt;
'''Figure 4:''' Once the device has been bound to a VFIO driver, set in a VFIO container, the VFIO container has it's IOMMU type set, and a memory map/page pin of the VFIO device has been completed a file descriptor can then be obtained for the device. This file descriptor can be used for interrupts (ioctls), to probe for information about the BAR regions, and configure the IRQs.&lt;br /&gt;
===VFIO device file descriptor ===&lt;br /&gt;
VFIO device file descriptors are divided into regions and each region is mapped into a device resource. Region count and info (file offset, allowable access, ect..) can be discovered through interrupt (IOCTL). Each file descriptor region corresponding to a PCI resource is represented as a file offset.  &lt;br /&gt;
&lt;br /&gt;
In the case of RPC Mode this structure is emulated whereas in SR-IOV Mode the structure is mapped to a real PCI resource. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BAR regions in a VGA PCI device.&lt;br /&gt;
!00:00.0 VGA compatible controller&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 Bar0 (Config Space) starts at offset 0&lt;br /&gt;
|-&lt;br /&gt;
|Region 1 Bar1 (MSI - Message Signaled Interrupts) &lt;br /&gt;
|-&lt;br /&gt;
|Region 2 Bar2 (MSIX)&lt;br /&gt;
|-&lt;br /&gt;
|Region 3 Bar3&lt;br /&gt;
|-&lt;br /&gt;
|Region 4 Bar4&lt;br /&gt;
|-&lt;br /&gt;
|Region 5 Bar5 (IO port space)&lt;br /&gt;
|-&lt;br /&gt;
|Expansion ROM&lt;br /&gt;
|}&lt;br /&gt;
Below is what the file offsets looks like internally for each BAR region starting from address 0 and growing with the addition of former regions as you progress through the file.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+VFIO representation of PCI BAR regions offsets.&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |&amp;lt;- File Offset -&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!0 -&amp;gt; A&lt;br /&gt;
! A -&amp;gt; (A+B)&lt;br /&gt;
!(A+B) -&amp;gt; (A+B+C)&lt;br /&gt;
!(A+B+C) -&amp;gt; (A+B+C+D)&lt;br /&gt;
!...&lt;br /&gt;
|-&lt;br /&gt;
|Region 0 (size A)&lt;br /&gt;
|Region 1 (size B)&lt;br /&gt;
|Region 2 (size C)&lt;br /&gt;
|Region 3 (size D)&lt;br /&gt;
|...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===VFIO Interrupts===&lt;br /&gt;
Guests communicate with the host via VFIO Interrupt Requests ([https://infogalactic.com/info/Interrupt_request_(PC_architecture) IRQs]). These are sent via an irqfd (IRQ [https://infogalactic.com/info/File_descriptor File Descriptor]). Similarly, the host receives these interrupts via [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] (Event File Descriptor). The resulting data can be returned via a [https://infogalactic.com/info/Callback_(computer_programming) callback].&lt;br /&gt;
&lt;br /&gt;
====IRQs====&lt;br /&gt;
Device properties discovered via interrupt (IOCTL).&lt;br /&gt;
&lt;br /&gt;
=====Get Device Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_device_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PCI &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_PLATFORM&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_DEVICE_FLAGS_RESET&lt;br /&gt;
|-&lt;br /&gt;
|num_irqs&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|num_regions&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
The IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_INFO&amp;lt;/code&amp;gt;''' can provide information to distinguish between PCI and platform devices as well as the number of regions and IRQs for a particular device.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L194 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L470 here]''', and '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L522 here]'''.&lt;br /&gt;
&lt;br /&gt;
=====Get Region Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_GET_REGION_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_region_info&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; |&lt;br /&gt;
|argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|cap_offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_CAPS&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_MMAP &lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_READ&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_REGION_INFO_FLAG_WRITE&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Once the interrupt user knows the number of regions within a VFIO device they can use IRQ '''&amp;lt;code&amp;gt;VFIO_DEVICE_GET_REGION_INFO&amp;lt;/code&amp;gt;''' to probe each region for additional information. This interrupt will return information such as if it can be read from or written to, if the device supports MMAP, as well as what the offset and size of the region is within the VFIO file descriptor. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read [https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L240 '''here (vfio.h)''']. &lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L425 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L545 '''here'''].&lt;br /&gt;
&lt;br /&gt;
===== Get IRQ Info=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | VFIO_DEVICE_GET_IRQ_INFO&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_info &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; |&lt;br /&gt;
| argz&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_INFO_AUTOMASKED&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
| VFIO_IRQ_INFO_MASKABLE&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_INFO_NORESIZE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_GET_IRQ_INFO'''&amp;lt;/code&amp;gt; is used to retrieve information about a device IRQ. &lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;code&amp;gt;VFIO_IRQ_INFO_AUTOMASKED&amp;lt;/code&amp;gt;''' is used to mask interrupts when they occur to protect the host. &lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L480 here (vfio.h)]'''&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' to service this request can be found [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L463 '''here'''], and [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L570 '''here'''].&lt;br /&gt;
&lt;br /&gt;
=====Set IRQs=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |VFIO_DEVICE_SET_IRQS&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |struct vfio_irq_set&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;12&amp;quot; |&lt;br /&gt;
|argz &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|data[]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|flags&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_MASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_TRIGGER&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_ACTION_UNMASK&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_BOOL&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_EVENTFD&lt;br /&gt;
|-&lt;br /&gt;
|VFIO_IRQ_SET_DATA_NONE&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|start&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;code&amp;gt;'''VFIO_DEVICE_SET_IRQS'''&amp;lt;/code&amp;gt; is used to setup IRQs. Actions can be configured such as trigger which is when the device triggers an interrupt (IOCTL), masking and unmasking actions can be set. Bool and None data types are used for loopback testing of the device. Start and index may be used to modify subregions.&lt;br /&gt;
&lt;br /&gt;
The upstream API can be read '''[https://github.com/torvalds/linux/blob/47700948a4abb4a5ae13ef943ff682a7f327547a/include/uapi/linux/vfio.h#L524 here (vfio.h)]'''.&lt;br /&gt;
&lt;br /&gt;
=== Device Decomposure/Recomposure ===&lt;br /&gt;
[[File:Device Decomposure and Recomposure via VFIO.png|alt=Figure 5: Device Decomposure and Recomposure via VFIO.|thumb|'''Figure 5:''' Device Decomposure and Recomposure via VFIO. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 5:''' Virtual Function IO (VFIO) devices are deconstructed in userspace into a set of VFIO primitives (MMIO pages, VFIO/IOMMU Groups, VFIO IRQs, File Descriptors). Recomposure of these devices occurs upon assignment of a Virtual Function (VF) to a QEMU virtual machine.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management Unit (MMU) ===&lt;br /&gt;
[[File:Figure 6- MMU - GMMU IOVA translation-isolation..png|alt=Figure 6: MMU - GMMU IOVA translation/isolation.|thumb|'''Figure 6:''' MMU - GMMU IOVA translation/isolation.]]&lt;br /&gt;
'''Figure 6:''' This section will touch upon the mechanisms used for enforcement of Host Physical Address (HPA) to Guest Physical Address (GPA) isolation.&lt;br /&gt;
&lt;br /&gt;
==== MMIO Isolation (Platform MMU) ====&lt;br /&gt;
The platform's CPU communicates with the GPU by reading/writing to and from pinned MMIO pages in [https://infogalactic.com/info/Random-access_memory Random Access Memory (RAM)]. MMIO pages within the RAM are subject to IO Virtual Address (IOVA) translations by the platform's discrete MMU controller which is programmed by the CPU. These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the platform.&lt;br /&gt;
&lt;br /&gt;
==== VRAM Isolation (GPU GMMU) ====&lt;br /&gt;
The GPU core performs virtualized operations by reading/writing to and from shadow page tables in onboard [[wikipedia:Video_random_access_memory|Video Random Access Memory (VRAM)]]. Shadow pages within the VRAM are subject to IO Virtual Address (IOVA) translations by the GPU's discrete GPU MMU controller (GMMU) which is programmed by the Embedded CPU (GPU co-processor). These IOVA translations serve as a mechanism to enforce HPA to GPA isolation in the context of the virtual GPUs and multi-process isolation in single user environments. &lt;br /&gt;
&lt;br /&gt;
==== Platform MMIO &amp;lt;-&amp;gt; GPU Shadow Pages ====&lt;br /&gt;
In the context of VFIO pinned MMIO pages in RAM act as an interface to communicate with VRAM shadow pages allowing GPU drivers on the platform to send instructions to the GPU. When the GPU or Platform alters memory contained in a shadow page or pinned MMIO page the change is mirrored in the corresponding IO Virtual Address (IOVA). For example if shadow page 0 is changed by the GPU this change is mirrored in MMIO page 0 on the platform (the reverse example also applies). When communications occur between the platform and GPU the information first moves through the MMU/GMMU and is then written to RAM/VRAM.&lt;br /&gt;
[[File:Figure 7- A depiction of region overlays within a VFIO file descriptor..png|alt=Figure 7: A depiction of region overlays within a VFIO file descriptor.|thumb|'''Figure 7:''' A depiction of region overlays within a VFIO file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
=== VFIO Quirks (region traps) ===&lt;br /&gt;
'''Figure 7:''' Regions of the PCI BAR require emulation (slow path) via emulated traps (known as quirks). These regions are primarily in PCI configuration space. QEMU may overlap a region overlay which when read/written to/from triggers a VM-exit to trap and emulate the region in order that appropriate translations may occur (such as those concerned with IO Virtual Address - IOVA).&lt;br /&gt;
[[File:Screen Shot 2022-05-06 at 10.46.59 AM.png|alt=Peer-to-Peer DMA Isolation under IOMMU|thumb|'''Figure 8:''' Peer-to-Peer DMA Isolation under IOMMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
=== Known IOMMU Issues ===&lt;br /&gt;
'''DMA Aliasing'''&lt;br /&gt;
&lt;br /&gt;
* Not all devices generate unique IDs.&lt;br /&gt;
* Not all devices generate IDs they should.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DMA Isolation'''&lt;br /&gt;
&lt;br /&gt;
* '''Figure 8:''' Peer-to-Peer DMA Isolation. In many circumstances IO Virtual Address (IOVA) translations do not occur properly in the context of DMA peering. Transactions that occur through the IOMMU are unaffected.&lt;br /&gt;
&lt;br /&gt;
[[File:Figure 0- Approches to GPU Virtualization..png|alt=Figure 0: Approches to GPU Virtualization.|thumb|'''Figure 0:''' Approaches to GPU Virtualization. See slides from: [https://open-iov.org/index.php/Virtual_I/O_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[61]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
==Mdev Mode==&lt;br /&gt;
'''Mdev Mode (VFIO Mediated Device)''' is a method of virtualizing I/O devices enabling full API capabilities without the requirement for hardware assistance.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Neo Jia, Kirti Wankhede, Kevin Tian, Yiying Zhang, David Cowperthwaite, Kun Tian, Yaozu Dong, Tina Zhang, Gerd Hoffmann, &amp;amp; Zhi Wang.&lt;br /&gt;
&lt;br /&gt;
See references 1, 7, 8, 17, 18, 19, 70 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Mediated Core ===&lt;br /&gt;
The mediated device framework made 3 major changes to the VFIO driver. &lt;br /&gt;
&lt;br /&gt;
* '''1: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_core.c Mediated core module (new)]'''  &amp;lt;br /&amp;gt;  -Mediated bus driver, create mediated device.  &amp;lt;br /&amp;gt;  -Physical device interface for vendor callbacks.  &amp;lt;br /&amp;gt;  -Generic Mediated device management user interface (sysfs).&lt;br /&gt;
* '''2: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/mdev/mdev_driver.c Mediated device module (new)]'''  &amp;lt;br /&amp;gt;  -Manage created mediated device, fully compatible with VFIO user API (UAPI).&lt;br /&gt;
* '''3: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/vfio/vfio_iommu_type1.c VFIO IOMMU driver (enhancement)]'''   &amp;lt;br /&amp;gt;  -VFIO IOMMU API Type1 compatible, easy to extend to non-Type1.&lt;br /&gt;
The full list of these changes can be seen in the [https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03922.html '''lists.gnu.org Qemu-devel''' mailing list archive].&lt;br /&gt;
&lt;br /&gt;
=== Device Initialization ===&lt;br /&gt;
This section will deal with how an Mdev driver is initialized.&lt;br /&gt;
&lt;br /&gt;
'''Sample mdev code''' for device initialization can be found '''[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L229 here]'''.&lt;br /&gt;
&lt;br /&gt;
==== Registering VFIO MDEV as a driver ====&lt;br /&gt;
VFIO Mdev must be registered as a driver. This register event occurs between the Mdev Driver Register Interface and the VFIO MDEV interface.&lt;br /&gt;
&lt;br /&gt;
==== Registering PCIE Device with the Mediated Core ====&lt;br /&gt;
[[File:Mdev-gpu.png|alt=Registering the mediated device.|thumb|'''Figure 9:''' Registering the mediated device. This step may be accomplished via the vendor driver or via [https://docs.linux-gvm.org/ GVM/Mdev-GPU] for drivers which do not include support for Mdev functionality and/or do not support arbitrary Mdev types.]]&lt;br /&gt;
'''Figure 9:''' The vendor driver must register with the Mediated Core's Device Register Interface. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Registering Mediated Callbacks (CBs) ====&lt;br /&gt;
'''Figure 9:''' The vendor driver must now register Mediated Callbacks which it expects to receive from Mdev devices. The example shown uses the [https://docs.linux-gvm.org/ GVM Project]'s [https://docs.linux-gvm.org/mdev-gpu/ Mdev-GPU] component to accomplish this step on behalf of the vendor driver.&lt;br /&gt;
&lt;br /&gt;
==== Creating a Mediated Device via mdev-sysfsdev API ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Echoing a UUID into the sysfsdev API.png|thumb|'''Figure 10:''' Echoing a UUID into the mdev-sysfsdev API. This functionality is included in [https://github.com/mdevctl/mdevctl mdevctl] and in [https://libvf.io/ LibVF.IO]. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 10:''' The user of an mdev capable device driver may echo values such as a UUID into the mdev-sysfsdev interface to create a unique mediated device. UUIDs must be unique per mdev device within a host.&lt;br /&gt;
[[File:QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor..png|alt=Figure 10: QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor.|thumb|'''Figure 11:''' QEMU creates VFIO-mdev IOMMU binding and acquires mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
==== QEMU adds VFIO device to IOMMU container-group ====&lt;br /&gt;
'''Figure 11:''' When starting a QEMU process with a VFIO-mdev attached QEMU calls the VFIO API to add the VFIO device to an IOMMU container/group. QEMU then runs the IOCTL to obtain a file descriptor for the device.&lt;br /&gt;
&lt;br /&gt;
==== QEMU passes mdev device file descriptor to VM ====&lt;br /&gt;
[[File:QEMU presenting the VFIO file descriptor into the virtual machine..png|alt=Figure 11: QEMU presenting the VFIO file descriptor into the virtual machine.|thumb|'''Figure 12:''' QEMU presenting the VFIO file descriptor into the virtual machine. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
'''Figure 12:''' Once QEMU has obtained the VFIO file descriptor for the Mdev device via IOCTL it is then QEMU's job to present the file descriptor into the virtual machine so that the mdev may be used by the guest.&lt;br /&gt;
&lt;br /&gt;
===Instruction Execution===&lt;br /&gt;
[[File:Ioeventfd-and-irqfd.png|thumb| '''Figure 13:''' A simple diagram of signalling from host to guest (via irqfd) &amp;amp; guest to host (via ioeventfd) From [http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd blog.allenx]]]&lt;br /&gt;
'''Figure 13:''' Mdev Mode moves instruction information across a virtual function (VF) device using [https://infogalactic.com/info/Remote_procedure_call Remote Procedure Calls] generally by way of [https://infogalactic.com/info/Interrupt software interrupt] ([https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]). Signals to and from the guest and the host GPU driver may be passed over file descriptors such as the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 Interrupt Request File Descriptor (irqfd)] and [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a IO Event File Descriptor (ioeventfd)]. &lt;br /&gt;
The irqfd may be used to signal from the host into the guest whereas the ioeventfd may be used to signal from the guest into the host. Guest GPU instructions which would normally serialize as pRPCs (physical Remote Procedure Calls) are instead serialized from the guest as vRPCs (virtual Remote Procedure Calls) which are executed by the host mediated driver.&lt;br /&gt;
&lt;br /&gt;
====IRQ remapping====&lt;br /&gt;
Interrupt Requests (IRQs) must be remapped (trapped for virtualized execution) to protect the host from sensitive instructions which may affect global memory state.&lt;br /&gt;
&lt;br /&gt;
==== Interrupt Injection ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
===Memory Management ===&lt;br /&gt;
Mdev memory management is handled by vendor driver software.&lt;br /&gt;
&lt;br /&gt;
====Region Passthrough====&lt;br /&gt;
Guests may be presented with emulated memory regions or via passthrough regions or a mixture of the two such as in the case of passthrough regions with BAR 0 configuration space emulation while other regions are passthrough'd.&lt;br /&gt;
&lt;br /&gt;
===== Emulated Regions =====&lt;br /&gt;
Emulated memory regions use indirect emulated communication requiring a VM-exit (slow). These regions are often used for virtual PCI config space such as [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/c0adb9957c0b22bfdbc18395e81dd2b476addac5/mdpy.c#L112 in this sample code].&lt;br /&gt;
&lt;br /&gt;
===== Passthrough Regions =====&lt;br /&gt;
Passthrough memory regions use direct communication requiring no VM-exit (fast).&lt;br /&gt;
&lt;br /&gt;
===== Region Access =====&lt;br /&gt;
[[File:QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs.png|alt=Figure 13: QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs|thumb|'''Figure 14:''' QEMU gets region info via VFIO UAPI from vendor driver through vfio-mdev and Mediated CBs. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 14:''' QEMU gets region information via VFIO User API (UAPI) from the vendor driver through VFIO-mdev and Mediated Callbacks.&lt;br /&gt;
[[File:Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation..png|alt=Figure 14: Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation.|thumb|'''Figure 15:''' Guest driver accessing Mdev MMIO space backed by mdev file descriptor triggers EPT violation. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 15:''' The guest's vendor driver accesses the Mdev MMIO trapped region backed by a mdev file descriptor (fd) which triggers an Extended Page Table (EPT) violation.&lt;br /&gt;
[[File:KVM services EPT violation and forwards to QEMU VFIO PCI driver..png|alt=Figure 15: KVM services EPT violation and forwards to QEMU VFIO PCI driver.|thumb|'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 16:''' KVM services EPT violation and forwards to QEMU VFIO PCI driver.&lt;br /&gt;
[[File:QEMU convert request from KVM to Read-Write acess to Mdev file descriptor..png|alt=Figure 16: QEMU convert request from KVM to Read/Write acess to Mdev file descriptor.|thumb|'''Figure 17:''' QEMU convert request from KVM to Read/Write acess to Mdev file descriptor. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 17:''' QEMU convert request from KVM to R/W access to Mdev file descriptor.&lt;br /&gt;
&lt;br /&gt;
==== EPT Page Violations====&lt;br /&gt;
Guest [https://infogalactic.com/info/Memory-mapped_I/O Memory Mapped IO (MMIO)] trips Extended Page Table (EPT) violations which are trapped by the host MMU. KVM services EPT violations and forwards to QEMU VFIO PCI driver. QEMU then converts the request from KVM to R/W access to the [https://infogalactic.com/info/File_descriptor Mdev File Descriptor (FD)]. Reads and writes are then handled by the host GPU device driver via mediated [https://infogalactic.com/info/Callback_(computer_programming) callbacks (CBs)] and [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO-mdev].&lt;br /&gt;
&lt;br /&gt;
==== Mediated DMA Translations ====&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
'''--Researching--'''&lt;br /&gt;
&lt;br /&gt;
'''--'''&lt;br /&gt;
&lt;br /&gt;
Because memory is not statically allocated by the vendor driver under the mediated device framework there is no requirement to make use of traditional VFIO pinned pages (via the vfio-pci module) rather MMIO memory can be mapped at runtime incrementally. As a result non-standard mediated device vfio stub modules may be used.&lt;br /&gt;
&lt;br /&gt;
'''Figure 18:''' Memory regions get added by QEMU.&lt;br /&gt;
[[File:Memory Regions Added by QEMU.png|alt=Memory Regions Added by QEMU|thumb|'''Figure 18:''' Memory Regions Added by QEMU. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
'''Figure 19:''' QEMU calls VFIO_DMA_MAP via Memory listener. (not just guest physical memory but also device memory will be added through this memory listener)&lt;br /&gt;
[[File:QEMU calls VFIO DMA MAP via Memory listener.png|alt=QEMU calls VFIO DMA MAP via Memory listener|thumb|'''Figure 19:''' QEMU calls VFIO DMA MAP via Memory listener. See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
[[File:Type 1 IOMMU Tracks VA-GFN.png|alt=Type 1 IOMMU Tracks VA-GFN|thumb|'''Figure 20:''' Type 1 IOMMU Tracks &amp;lt;VA, GFN&amp;gt;.  See slides from: [https://open-iov.org/index.php/Mediated_Device_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[1]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
'''Figure 20:''' Type 1 IOMMU tracks &amp;lt;VA, GFN (Guest Frame Number)&amp;gt;. We build a table to list the QEMU VAs and track the their mapping relation to Guest Frame Numbers (GFNs).&lt;br /&gt;
===Scheduling===&lt;br /&gt;
&lt;br /&gt;
Scheduling is handled by the host mdev driver.&lt;br /&gt;
&lt;br /&gt;
=== Kernel API ===&lt;br /&gt;
Kernel documentation used for implementing a VFIO Mediated Device may be found at [https://www.kernel.org/doc/html/latest/driver-api/vfio-mediated-device.html kernel.org].&lt;br /&gt;
&lt;br /&gt;
=== Sample Code ===&lt;br /&gt;
Sample code for various mdev implementations may be found below:&lt;br /&gt;
&lt;br /&gt;
'''Mediated Virtual PCI Display Host Device:''' &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c]&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c].&lt;br /&gt;
&lt;br /&gt;
'''Serial PCI Port-based Mediated Device:'''  &lt;br /&gt;
&lt;br /&gt;
# [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c]. &lt;br /&gt;
&lt;br /&gt;
====== Compilation ======&lt;br /&gt;
To compile the kernel modules linked above you should have your distro's equivalent of the build-essential package installed. The included Makefile should provide all that is necessary to successfully compile the kernel modules. You can type the following command to compile the modules from within the directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the make operation has been completed successfully the directory will now contain .ko files. These files are the binary kernel modules. &lt;br /&gt;
&lt;br /&gt;
====== Loading Kernel Modules ======&lt;br /&gt;
Now that you have compiled the kernel modules you may load them via the insmod command.&lt;br /&gt;
&lt;br /&gt;
For example to load the '''mtty.ko''' module run the following command from within the directory where you built the modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;insmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Unloading Kernel Modules ======&lt;br /&gt;
To unload any of the kernel modules you may make use of the rmmod command.&lt;br /&gt;
&lt;br /&gt;
For example to unload the '''mtty.ko''' module run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rmmod mtty.ko&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Additional Documentation ======&lt;br /&gt;
An additional guide explaining how to make use of the mtty.c sample code may be found at [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294#n308 line 308] of the kernel.org VFIO Mediated Device documentation.&lt;br /&gt;
=== Mdev Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Software HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
==SR-IOV Mode==&lt;br /&gt;
'''SR-IOV Mode (Single Root I/O Virtualization)''' involves hardware assisted virtualization on I/O peripherals.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zheng Xiao, Jerry Jiang, &amp;amp; Ken Xue.&lt;br /&gt;
&lt;br /&gt;
See reference 6 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== Instruction Execution===&lt;br /&gt;
SR-IOV communicates instructions from a virtual function (VF) directly to the [https://infogalactic.com/info/PCI_configuration_space PCI BAR]. &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Guests are presenting with passthrough memory regions by the device firmware.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling===&lt;br /&gt;
Scheduling may be handled by the host mdev driver and/or the device firmware.&lt;br /&gt;
=== SR-IOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SR-IOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
== SIOV Mode ==&lt;br /&gt;
'''SIOV (Scalable I/O Virtualization)''' involves the combination of concepts form both [https://open-iov.org/index.php/Mediated_Device_Internals#SR-IOV_Mode SR-IOV Mode] and [https://open-iov.org/index.php/Mediated_Device_Internals#Mdev_Mode Mdev Mode] as well as novel concepts like shared IOMMU aware buffers and offloading of PCI config space VM-exits (slow path) to a discrete controller.&lt;br /&gt;
&lt;br /&gt;
'''Revision 1.0 of the SIOV specification''' can be read on the [https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Open Compute Project website].&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Kevin Tian, Tina Zhang, Xin Zeng, Yi Liu.&lt;br /&gt;
&lt;br /&gt;
See references 3, 4, 5, 16, 17, 18, 19, 20, 21 in the [https://open-iov.org/index.php/Virtual_IO_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
Enhancements to [https://edc.intel.com/content/www/us/en/design/ipla/software-development-platforms/client/platforms/alder-lake-desktop/12th-generation-intel-core-processors-datasheet-volume-1-of-2/002/intel-virtualization-technology-for-directed-i-o/ Intel VT-d] introduce new 'Scalable Mode' to allow the platform to assign more granular IOMMU allocations to mediated devices ([https://open-iov.org/index.php/Mediated_Device_Internals#Memory_Management mdev memory management]). This change is referred to as an IOMMU Aware Mediated Device.&lt;br /&gt;
&lt;br /&gt;
==== IOMMU Aware Mediated Device ====&lt;br /&gt;
SIOV made several changes to the VFIO driver, Intel IOMMU, and Mediated Device Framework. &lt;br /&gt;
&lt;br /&gt;
The full list of these changes can be seen in the [https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ mailing list archive on '''lwn.net''' under '''(vfio/mdev: IOMMU aware mediated device)'''].&lt;br /&gt;
&lt;br /&gt;
==== Shared Hardware Workqueues ====&lt;br /&gt;
SIOV makes use of Shared Hardware Workqueues which may be accessed by processes or Virtual Machines.&lt;br /&gt;
&lt;br /&gt;
[https://www.kernel.org/doc/html/latest/x86/sva.html According to '''kernel.org''']: ''&amp;quot;In order to allow the hardware to distinguish the context for which work is being executed in the hardware by SWQ interface, SIOV uses Process Address Space ID (PASID), which is a 20-bit number defined by the PCIe SIG. PASID value is encoded in all transactions from the device. This allows the IOMMU to track I/O on a per-PASID granularity in addition to using the PCIe Resource Identifier (RID) which is the Bus/Device/Function.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== SIOV Mode Requirements ===&lt;br /&gt;
Driver Support.&lt;br /&gt;
&lt;br /&gt;
Device SIOV support.&lt;br /&gt;
&lt;br /&gt;
Firmware HPA&amp;lt;-&amp;gt;GPA Boundary Enforcement.&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
&lt;br /&gt;
# [https://www.youtube.com/watch?v=Xs0TJU_sIPc &amp;lt;nowiki&amp;gt;[2016] vGPU on KVM - A VFIO Based Framework by Neo Jia &amp;amp; Kirti Wankhede&amp;lt;/nowiki&amp;gt;] - [https://www.linux-kvm.org/images/5/59/02x03-Neo_Jia_and_Kirti_Wankhede-vGPU_on_KVM-A_VFIO_based_Framework.pdf slides]&lt;br /&gt;
# [https://www.youtube.com/watch?v=WFkdTFTOTpA &amp;lt;nowiki&amp;gt;[2016] An Introduction to PCI Device Assignment with VFIO by Alex Williamson&amp;lt;/nowiki&amp;gt;] - [http://events17.linuxfoundation.org/sites/events/files/slides/An%20Introduction%20to%20PCI%20Device%20Assignment%20with%20VFIO%20-%20Williamson%20-%202016-08-30_0.pdf slides]&lt;br /&gt;
#[https://events19.linuxfoundation.cn/wp-content/uploads/2017/11/Intel%C2%AE-Scalable-I_O-Virtualization_Kevin-Tian.pdf &amp;lt;nowiki&amp;gt;[2017] Scalable I/O Virtualization by Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=G6D-jaCs6sc &amp;lt;nowiki&amp;gt;[2019] Bring a Scalable IOV Capable Device into Linux World by Xin Zeng &amp;amp; Yi Liu&amp;lt;/nowiki&amp;gt;] - [https://static.sched.com/hosted_files/kvmforum2019/5e/Bring%20a%20scalable%20IOV%20capable%20device%20into%20Linux%20-%20KVM%202019.pdf slides]&lt;br /&gt;
#[https://www.opencompute.org/documents/ocp-scalable-io-virtualization-technical-specification-revision-1-v1-2-pdf Scalable I/O Virtualization Revision 1.0]&lt;br /&gt;
#[https://www.youtube.com/watch?v=_tB3EbFDcRQ &amp;lt;nowiki&amp;gt;[2018] Live Migration Support for GPU with SRIOV by Zheng Xiao, Jerry Jiang &amp;amp; Ken Xue&amp;lt;/nowiki&amp;gt;] - [https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Live-Migration-Support-for-GPU-with-SRIOV-Challenges-and-Solution-Zheng-Xiao-Alibaba-Cloud-Jerry-Jiang-Ken-Xue-AMD.pdf slides]&lt;br /&gt;
#[https://www.youtube.com/watch?v=UODxW1opfn0 &amp;lt;nowiki&amp;gt;[2017] Intel GVT-g: From Production to Upstream - Zhi Wang, Intel&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=DKYvQ3FdFeo &amp;lt;nowiki&amp;gt;[2016] Qemu Graphics Update 2016 by Gerd Hoffmann&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
# [https://man7.org/linux/man-pages/man2/eventfd.2.html eventfd] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/eventfd.c root/virt/kvm/eventfd.c]&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 KVM: irqfd])&lt;br /&gt;
# (kernel diff:: [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34e6b175e61821026893ec5298cc8e7558df43a KVM: add ioeventfd support])&lt;br /&gt;
# [https://web.archive.org/web/20220120223711/http://blog.allenx.org/2015/07/05/kvm-irqfd-and-ioeventfd KVM irqfd &amp;amp; ioeventfd]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio.rst VFIO - Virtual Function I/O] - [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/virt/kvm/vfio.c root/virt/kvm/vfio.c]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst VFIO Mediated Devices]&lt;br /&gt;
#[https://lwn.net/ml/linux-kernel/20190222021927.13132-1-baolu.lu@linux.intel.com/ IOMMU Aware Mediated Device]&lt;br /&gt;
# [https://www.youtube.com/watch?v=95KSKrZM8oQ Hardware-Assisted Mediated Pass-Through with VFIO by Kevin Tian]&lt;br /&gt;
# [https://www.youtube.com/watch?v=cHMLBcHplhk &amp;lt;nowiki&amp;gt;[2017] Generic Buffer Sharing Mechanism for Mediated Devices by Tina Zhang&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://www.youtube.com/watch?v=KWRKx_uxUDI &amp;lt;nowiki&amp;gt;[2019] Toward a Virtualization World Built on Mediated Pass-Through - Kevin Tian&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
# [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/auxiliary_bus.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 Auxiliary Bus]&lt;br /&gt;
#[https://www.kernel.org/doc/html/latest/x86/sva.html Shared Virtual Addressing]&lt;br /&gt;
#[https://vfio.blogspot.com/ vfio.blogspot.com]&lt;br /&gt;
#[https://01.org/sites/default/files/xengt.pdf XenGT by Kevin Tian]&lt;br /&gt;
#[https://web.archive.org/web/20130721094438/http://labs.vmware.com/academic/publications/gpu-virtualization VMWare Academic Publications: GPU Virtualization by Micah Dowty &amp;amp; Jeremy Sugerman]&lt;br /&gt;
#[https://pcisig.com/specifications/iov PCI SIG I/O Virtualization]&lt;br /&gt;
#[https://web.archive.org/web/20120108034526/http://sysweb.cs.toronto.edu/vmgl VMGL by the University of Toronto Computer Science Department]&lt;br /&gt;
#[https://web.archive.org/web/20120518125815/http://www.nvidia.com/object/vgx-hypervisor.html Kepler VGX Hypervisor]&lt;br /&gt;
#[https://web.archive.org/web/20090218010221/http://software.intel.com/en-us/articles/intel-virtualization-technology-for-directed-io-vt-d-enhancing-intel-platforms-for-efficient-virtualization-of-io-devices Intel Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices]&lt;br /&gt;
#[https://lwn.net/2001/0712/a/dma-interface.php3 DMA-Mapping.txt (Dynamic DMA Mapping)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_guangrong.pdf KVM MMU Virtualization by Xiao Guangrong]&lt;br /&gt;
#[https://wiki.osdev.org/PCI OSDEV: PCI]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 Down to the TLP: How PCI express devices talk (Part I)]&lt;br /&gt;
#[http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-2 Down to the TLP: How PCI express devices talk (Part II)]&lt;br /&gt;
#[https://projectacrn.github.io/latest/tutorials/sriov_virtualization.html Intel ACRN: Enabling SR-IOV Virtualization]&lt;br /&gt;
#[https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-bus-pci Kernel.org sysfs-bus-pci]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html Linux Kernel Labs: Memory Mapping]&lt;br /&gt;
#[https://rayanfam.com/topics/inside-windows-page-frame-number-part1/ Inside Windows Page Frame Number (PFN) - Part 1]&lt;br /&gt;
#[https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure Direct Rendering Infrastructure (DRI)]&lt;br /&gt;
#[https://dri.sourceforge.net/doc/DRIuserguide.html DRI User Guide]&lt;br /&gt;
#[https://linux-kernel-labs.github.io/refs/heads/master/lectures/virt.html#i-o-virtualization Linux Kernel Labs: IO Virtualization]&lt;br /&gt;
#[https://dri.freedesktop.org/doxygen/gallium/ Gallium3D: Main Page]&lt;br /&gt;
#[https://web.archive.org/web/20080107043445/http://www.tungstengraphics.com/wiki/index.php/Gallium3D Gallium3D Wiki]&lt;br /&gt;
#[https://web.archive.org/web/20090219182518/http://www.tungstengraphics.com/wiki/files/gallium3d-xds2007.pdf Gallium3D talk from XDS 2007]&lt;br /&gt;
#[https://projectacrn.github.io/latest/developer-guides/hld/hv-memmgt.html Memory Management High Level Design (ARCN)]&lt;br /&gt;
#[https://web.archive.org/web/20080111122628/http://www.digit-life.com/articles2/gffx/nv40-part1-a.html Block Architecture Diagrams for Geforce series]&lt;br /&gt;
#[http://freenv.svn.sourceforge.net/viewvc/freenv/doc/shaderinsnformat/bitdiagen/ Block diagrams for 40 series instruction format]&lt;br /&gt;
#[[wikipedia:PCI_configuration_space|PCI Configuration Space]]&lt;br /&gt;
#[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/gpu-virtual-memory-in-wddm-2-0 GPU virtual memory in WDDM 2.0]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://airbus-seclab.github.io/qemu_blog/pci_slave.html A deep dive into QEMU: PCI slave devices]&lt;br /&gt;
#[https://qemu-project.gitlab.io/qemu/system/gdb.html Debugging QEMU Guests with GDB (start &amp;amp; stop, examine state like registers &amp;amp; memory, set breakpoints &amp;amp; watchpoints)]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://wiki.archlinux.org/title/intel_graphics Arch Wiki: Intel Graphics]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf An Introduction to Intel Graphics Virtualization Technology (legacy GVT-g) by Zhi Wang]&lt;br /&gt;
#[https://patchwork.kernel.org/project/qemu-devel/patch/1478293856-8191-11-git-send-email-kwankhede@nvidia.com/ Kernel.org: vfio iommu type1: Add support for mediated devices]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://www.blackhat.com/docs/us-14/materials/us-14-Torrey-MoRE-Shadow-Walker-The-Progression-Of-TLB-Splitting-On-x86.pdf More Shadow Walker: The Progression of TLB-Splitting on x86]&lt;br /&gt;
#[https://revers.engineering/mmu-ept-technical-details/ MMU Virtualization Via Intel EPT: Technical Details]&lt;br /&gt;
#[https://github.com/awilliam/linux-vfio/tree/next Alex Williamson Github: VFIO Development (tree next)]&lt;br /&gt;
#[https://events.static.linuxfound.org/slides/2011/linuxcon-japan/lcj2011_linming.pdf GPU PMU: performance monitoring with perf event]&lt;br /&gt;
#[https://book.systemsapproach.org/e2e/rpc.html Remote Procedure Call (RPC)]&lt;br /&gt;
#[http://www.virtualopensystems.com/en/products/api-remoting/ Virtual Open Systems: API Remoting]&lt;br /&gt;
#[https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian A Full GPU Virtualization Solution with Mediated Pass-Through by Yiying Zhang, David Cowperthwaite, Kun Tian, and Yaozu Dong] - [https://www.usenix.org/system/files/conference/atc14/atc14-paper-tian.pdf &amp;lt;nowiki&amp;gt;[Paper]&amp;lt;/nowiki&amp;gt;] - [https://www.youtube.com/watch?v=vvYmDQKZ6MQ &amp;lt;nowiki&amp;gt;[Video]&amp;lt;/nowiki&amp;gt;] - [https://www.usenix.org/sites/default/files/conference/protected-files/atc14_slides_tian.pdf &amp;lt;nowiki&amp;gt;[Slides 1]&amp;lt;/nowiki&amp;gt;] - [https://cseweb.ucsd.edu/~yiying/cse291j-winter20/reading/GPU-Virtualization.pdf &amp;lt;nowiki&amp;gt;[Slides 2]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
#[https://www.youtube.com/watch?v=-iuIu7_GuEo &amp;lt;nowiki&amp;gt;[2014] KvmGT: A Full GPU Virtualization Solution by Jike Song&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23761</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23761"/>
		<updated>2023-03-23T04:57:30Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
|RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-guest&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the nvidia-vgpu-mgr process.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for GuC-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/ikwzm/udmabuf udmabuf], [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for GSP-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on LibOS containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|Systemd, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the nvidia-vgpu-mgr process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidiavgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://open-iov.org/index.php/GPU_Driver_Internals#RM_API RMAPI], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with nvidia-vgpu-mgr.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia_vgpu_vfio&lt;br /&gt;
|Driver&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23760</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23760"/>
		<updated>2023-03-23T04:45:40Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* GVM Integration Documents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== GVM Integration Documents ===&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia] &lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD] &lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://linux-gvm.org/ GPU Virtual Machine (GVM)]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23759</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23759"/>
		<updated>2023-03-23T04:42:50Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* Gpuvm Integration Documents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== GVM Integration Documents ===&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia] &amp;lt;sup&amp;gt;(support documentation up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD]  &amp;lt;sup&amp;gt;(support documentation not up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://linux-gvm.org/ GPU Virtual Machine (GVM)]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23758</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23758"/>
		<updated>2023-03-23T04:42:25Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* GVM Integration Documents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== Gpuvm Integration Documents ===&lt;br /&gt;
[[Intel SR-IOV APIs|Intel]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM Nvidia] &amp;lt;sup&amp;gt;(support documentation up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU AMD]  &amp;lt;sup&amp;gt;(support documentation not up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://linux-gvm.org/ GPU Virtual Machine (GVM)]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Intel&amp;diff=23757</id>
		<title>Intel</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Intel&amp;diff=23757"/>
		<updated>2023-03-23T04:42:14Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will document points of integration for virtualization in the Intel i915 driver.&lt;br /&gt;
&lt;br /&gt;
The i915 added '''SR-IOV feature enablement''' in [https://github.com/intel/linux-intel-lts/commit/41ef979f0894326c202473807a56b599a2f3d04e this commit (April 26th 2022)]. Work is ongoing to upstream this code to [https://github.com/torvalds/linux/tree/master/drivers/gpu/drm/i915 i915 in the mainline Linux kernel].&lt;br /&gt;
&lt;br /&gt;
Driver API documentation can be read here: https://01.org/linuxgraphics/gfx-docs/drm/gpu/i915.html&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Intel_SR-IOV_APIs&amp;diff=23756</id>
		<title>Intel SR-IOV APIs</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Intel_SR-IOV_APIs&amp;diff=23756"/>
		<updated>2023-03-23T04:26:24Z</updated>

		<summary type="html">&lt;p&gt;Arthur: Arthur moved page Intel SR-IOV APIs to Intel&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Intel]]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Intel&amp;diff=23755</id>
		<title>Intel</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Intel&amp;diff=23755"/>
		<updated>2023-03-23T04:26:24Z</updated>

		<summary type="html">&lt;p&gt;Arthur: Arthur moved page Intel SR-IOV APIs to Intel&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will document the functions of Intel i915 for use with Single Root I/O Virtualization (SR-IOV) and VFIO-Mediate Device (VFIO-Mdev).&lt;br /&gt;
&lt;br /&gt;
The i915 added '''SR-IOV feature enablement''' in [https://github.com/intel/linux-intel-lts/commit/41ef979f0894326c202473807a56b599a2f3d04e this commit (April 26th 2022)]. Work is ongoing to upstream this code to [https://github.com/torvalds/linux/tree/master/drivers/gpu/drm/i915 i915 in the mainline Linux kernel].&lt;br /&gt;
&lt;br /&gt;
Driver API documentation can be read here: https://01.org/linuxgraphics/gfx-docs/drm/gpu/i915.html&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23754</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23754"/>
		<updated>2023-03-22T23:02:22Z</updated>

		<summary type="html">&lt;p&gt;Arthur: /* References (Talks &amp;amp; Reading Material) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidiavgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr) and a library (libnvidiavgpu.so).&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol05-memory_views.pdf &amp;lt;nowiki&amp;gt;i915: Kaby Lake Intel Graphics Programmer's Reference Manual [Volume 5: Memory Views]&amp;lt;/nowiki&amp;gt;]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23753</id>
		<title>GPU Driver Internals</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Driver_Internals&amp;diff=23753"/>
		<updated>2023-03-22T17:53:19Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will detail the internals of various GPU drivers for use with I/O Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization. &lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Article Structure ==&lt;br /&gt;
This article will aim to provide information about the following details of GPU drivers:&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
This section will detail high level architectures of each driver.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
This section will cover how the GPU's embedded components, the GPU driver, and virtualization functions are initialized.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
This section will detail how the device schedules instructions for execution.&lt;br /&gt;
&lt;br /&gt;
This will attempt to provide a comprehensive view of scheduling from virtualized processes down to execution within the device.&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
The In-VM Scheduling section will detail how instructions scheduled within the virtual machine's GPU device driver.&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
The Between-VM Scheduling section will detail how the host kernel module and/or virtual GPU helper functions handle scheduling / context swaps between virtual machines on a computer system.&lt;br /&gt;
&lt;br /&gt;
==== Firmware Scheduling (if applicable) ====&lt;br /&gt;
The Firmware Scheduling section will cover the GPU's internal scheduling model if a deferred execution pathway is used (like i915's GuC or OpenRM's GSP).&lt;br /&gt;
&lt;br /&gt;
In the case an intermediate scheduling microcontroller is not used this section may be less applicable (ie: vExeclist scheduling under Intel vGPUs).&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
The Memory Management section will cover how the GPU driver manages memory for virtual GPUs and host processes.&lt;br /&gt;
&lt;br /&gt;
This will aim detail paging abstractions used for global memory translation, and per-process memory translation.&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Display Surface Virtualization section will detail how virtual displays are provided to guests and/or graphics rendering buffers (pixel surfaces) are shared from guest to host if such functions are provided via the driver.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
This section will cover methods provided by the GPU driver suitable for high performance graphics sharing.&lt;br /&gt;
&lt;br /&gt;
== i915 ==&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Resources Used ===&lt;br /&gt;
This section is supported by significant contributions in open source by Zhi Wang, Ben Widawsky, and Igor Bogdanov.&lt;br /&gt;
&lt;br /&gt;
See references 2, 3, 4, 5, 6, 7, 8, and 9 in the [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) References (Talks &amp;amp; Reading Material)] section.&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
&lt;br /&gt;
==== i915 Clients ====&lt;br /&gt;
Processes which make use of the Intel i915 driver receive an i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During initialization of the i915 driver the GuC binary blob is offloaded into the Graphics Translation Table (GTT). This allows the GuC to read GTT-loaded binary blob from shared framebuffer memory so that it may boot.&lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
[[File:Figure 0- i915 vGPU Scheduling.png|alt=Figure 0: i915 vGPU Scheduling|thumb|'''Figure 0:''' i915 vGPU high-level Scheduling. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
* Guest kernel (i915.ko)&lt;br /&gt;
* Host kernel (i915.ko)&lt;br /&gt;
* Device Firmware (GuC)&lt;br /&gt;
&lt;br /&gt;
===== In-VM Scheduling =====&lt;br /&gt;
===== Guest kernel (i915.ko) =====&lt;br /&gt;
&lt;br /&gt;
====== vExeclist ======&lt;br /&gt;
The vExeclist is a method to submit commands directly to the GPU without the use of an intermediate microcontroller.&lt;br /&gt;
&lt;br /&gt;
====== vGuC ======&lt;br /&gt;
vGuC is a command submission interface used to process commands to the Intel [https://open-iov.org/index.php/GPU_Firmware#GuC Graphics Microcontroller (GuC)].&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
[[File:I915 Scheduling Events and Requests.png|alt=Figure 1: i915 vGPU Scheduling Requests &amp;amp; Events|thumb|'''Figure 1:''' i915 vGPU Scheduling Requests &amp;amp; Events. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (i915.ko) =====&lt;br /&gt;
Submitting commands to the GPU under i915 can take several paths. One pathway makes use of direct command submission without an intermediate micro-controller whereas the other uses an intermediate micro-controller. The intermediate micro-controller approach increases the amount of binary-blob code used and abstracts the kernel module from the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
====== Execlist ======&lt;br /&gt;
Execlist executes commands synchronously on the device without an intermediate microcontroller. This is the preferred method of executing commands by some driver developers because of it's stability and transparency under current i915 development.&lt;br /&gt;
&lt;br /&gt;
====== GuC ======&lt;br /&gt;
GuC provides an execution pathway with an intermediate microcontroller providing a scheduling abstraction for Intel's preferred internal scheduling model.&lt;br /&gt;
[[File:Figure 2- Intel vGPU Scheduler.png|alt=Figure 2: Intel vGPU Scheduler request flow.|thumb|'''Figure 2:''' i915 vGPU Scheduler request flow. See slides from: [https://open-iov.org/index.php/GPU_Driver_Internals#References_(Talks_&amp;amp;_Reading_Material) &amp;lt;nowiki&amp;gt;[9]&amp;lt;/nowiki&amp;gt;]]]&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GuC) =====&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== GTT (Graphics Translation Table) ======&lt;br /&gt;
GPU Memory on-device is a part of a GTT or Graphics Translation Table. This table stores information globally for all graphics processes within the system. Some processes access the Global Graphics Translation Table (GGTT) such as [[wikipedia:Direct_Rendering_Infrastructure|DRI]] while other's receive a Per Process Graphics Translation Table (PPGTT) buffer based on their i915 Client ID.&lt;br /&gt;
&lt;br /&gt;
====== GGTT (Global Graphics Translation Table) ======&lt;br /&gt;
&lt;br /&gt;
====== PPGTT (Per Process Graphics Translation Table) ======&lt;br /&gt;
Process-specific memory buffers are stored inside a Per Process Graphics Translation Table or PPGTT. This is a [https://open-iov.org/index.php/Virtual_IO_Internals#VRAM_Isolation_(GPU_GMMU) GPU MMU] translated subregion or IOVA of global GPU memory specific to a GPU process's client ID.&lt;br /&gt;
&lt;br /&gt;
====== Aliasing PPGTT ======&lt;br /&gt;
&lt;br /&gt;
====== Real PPGTT ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
The Intel vGPU makes use of two modes for Display Surface Virtualization.&lt;br /&gt;
&lt;br /&gt;
* VirtIO-GPU (Linux)&lt;br /&gt;
* Indirect Display Driver (Windows)&lt;br /&gt;
&lt;br /&gt;
==== VirtIO-GPU ====&lt;br /&gt;
&lt;br /&gt;
==== IDD (Indirect Display Driver) ====&lt;br /&gt;
The IDD ([https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver]) provides virtual display functions with arbitrary resolutions to any rendering device virtual or physical.&lt;br /&gt;
&lt;br /&gt;
Intel's IDD can be found in their [https://github.com/intel/Display-Virtualization-for-Windows-OS/ Display Virtualization for Windows OS] repository.&lt;br /&gt;
&lt;br /&gt;
==== Graphics Buffer Sharing ====&lt;br /&gt;
Intel's i915 driver provides functionality to directly map display memory from a [https://open-iov.org/index.php/Merged_Drivers guest vGPU Virtual Function (either SR-IOV or VFIO-Mdev) into the host GPU's Physical Function] without slow memory copies or graphics compression. For users running GPU virtualization on their local device this results in a significant performance uplift compared to traditional graphics sharing functionality built for remote access use-cases such as VDI.&lt;br /&gt;
&lt;br /&gt;
Intel's [https://github.com/intel/Display-Virtualization-for-Windows-OS 0copy display virtualization tools] are simple to implement as sharing does not rely upon an added [https://www.qemu.org/docs/master/system/devices/ivshmem.html IVSHMEM (Inter-VM Shared Memory device)] - rather the host directly maps the guest's display memory via [https://lwn.net/Articles/758903/ udmabuf]  as the buffer sharing functions are provided within the i915 open source driver.&lt;br /&gt;
&lt;br /&gt;
== OpenRM ==&lt;br /&gt;
[[File:Figure 3- GPU BAR to Timeshared Syhededuling via Channel IO.png|alt=Figure 3: GPU BAR to Timeshared Syhededuling via Channel IO|thumb|'''Figure 3:''' GPU BAR to Timeshared Scheduling via Channel IO.]]&lt;br /&gt;
&lt;br /&gt;
=== High Level Architecture ===&lt;br /&gt;
The Open Resource Manager (RM driver) makes use of a highly object oriented paradigm comprised of multiple &amp;quot;engines&amp;quot; which act as micro-services for servicing driver requests.&lt;br /&gt;
&lt;br /&gt;
The Open Resource Manager driver (also known as [https://open-iov.org/index.php/OpenRM OpenRM]) refers to Nvidia's [https://github.com/NVIDIA/open-gpu-kernel-modules open-kernel-modules].&lt;br /&gt;
&lt;br /&gt;
Broadly speaking the OpenRM driver consists of two parts.&lt;br /&gt;
&lt;br /&gt;
* The Platform RM (OpenRM)&lt;br /&gt;
* The Firmware RM (GSP RM / RM Core)&lt;br /&gt;
The Platform RM is loaded into the Linux Kernel as nvidia.ko. This module communicates with the GSP RM for via [[wikipedia:Remote_procedure_call|Remote Procedure Calls (RPCs)]] to communicate with engines from the RM Core.&lt;br /&gt;
&lt;br /&gt;
===== RM Clients =====&lt;br /&gt;
Processes (local, remote, or virtualized) which make use of the RM driver receive an RM Client ID. &lt;br /&gt;
&lt;br /&gt;
==== RM Server ====&lt;br /&gt;
The RM Server (or Resource Server) tracks RM Clients as well as the hardware and software resources they control, allocate, and free.&lt;br /&gt;
&lt;br /&gt;
==== RM API ====&lt;br /&gt;
API to control the Resource Manager Server.&lt;br /&gt;
&lt;br /&gt;
==== RM Core ====&lt;br /&gt;
Core functions of the RM driver controlling resource locking, mapping, unmapping, control calls, constructors, and deconstructors.&lt;br /&gt;
&lt;br /&gt;
=== Initialization ===&lt;br /&gt;
During bring up of the hardware several binary blobs are loaded from embedded [[wikipedia:Boot_ROM|Boot ROM]] memory to bootstrap embedded controller bring up from which point additional software is loaded from onboard [[wikipedia:Serial_Peripheral_Interface|SPI]] flash memory. &lt;br /&gt;
&lt;br /&gt;
Software loaded from SPI flash is necessary for the full initialization of the Falcon/NvRISC processor as well as a cached version of the software necessary to run the GPU System Processor (GSP). &lt;br /&gt;
&lt;br /&gt;
Once the platform is posted it is ready to communicate with the host platform's RM driver. The OpenRM driver offloads a binary blob containing the RM Core to the [https://open-iov.org/index.php/GPU_Firmware#GSP GPU System Processor (GSP)] which is likely to contain a more recent version than the cached version contained in on-board SPI flash. &lt;br /&gt;
&lt;br /&gt;
=== Scheduling ===&lt;br /&gt;
There are several abstractions for GPU virtual machine scheduling. Those are as follows:&lt;br /&gt;
&lt;br /&gt;
* Guest kernel (nvidia.ko)&lt;br /&gt;
* Host kernel (nvidia.ko)&lt;br /&gt;
*Host usermode (gpu-mgr / libnvidiavgpu.so)&lt;br /&gt;
* Device Firmware (GSP)&lt;br /&gt;
&lt;br /&gt;
==== Command Submission ====&lt;br /&gt;
&lt;br /&gt;
===== Runlist =====&lt;br /&gt;
&lt;br /&gt;
==== In-VM Scheduling ====&lt;br /&gt;
Virtual machines contain their own GPU scheduling within the Nvidia kernel module in the guest OS.&lt;br /&gt;
&lt;br /&gt;
===== Guest kernel (nvidia.ko) =====&lt;br /&gt;
Within a virtual machine running the Nvidia driver messages to the GPU are first sent to the guest nvidia.ko kernel module.&lt;br /&gt;
&lt;br /&gt;
The guest then determines whether a vRPC (virtual Remote Procedure Call) or a pRPC (physical Remote Procedure Call) should be sent. Both pRPCs and vRPCs are sent through the host RM driver (Resource Manager).&amp;lt;blockquote&amp;gt;''Note: Unclear on execution pathway for pRPCs vs vRPCs. pRPCs may go directly to device.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Between-VM Scheduling ====&lt;br /&gt;
In addition to scheduling which occurs within the virtual machine the Resource Manager driver also schedules messages to the GPU between GPU-accelerated virtual machines and host processes.&lt;br /&gt;
&lt;br /&gt;
===== Host kernel (nvidia.ko) =====&lt;br /&gt;
Messages sent by the guest (via vRPC or pRPC) are received by the host Nvidia.ko driver.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko contains a virtual GPU state machine which contains status information for the virtual GPU.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains a virtual GPU kernel scheduler which interacts with virtual GPU objects.&lt;br /&gt;
&lt;br /&gt;
Nvidia.ko also contains an RM Call scheduler which schedules calls on an RM class.&lt;br /&gt;
&lt;br /&gt;
The Nividia.ko kernel module exits to userspace to execute the nvidia-vgpu-mgr and VMIOP (Virtual Machine Input Output Plugin).&lt;br /&gt;
&lt;br /&gt;
===== Host usermode (nvidia-vgpu-mgr / libnvidiavgpu.so) =====&lt;br /&gt;
After exiting to userspace a daemon process (the nvidia-vgpu-mgr) and a library (libnvidiavgpu.so).&lt;br /&gt;
&lt;br /&gt;
===== nvidia-vgpu-mgr =====&lt;br /&gt;
The nvidia-vgpu-mgr is a process which provides the spawning of virtual GPU stubs and population with capability information.&lt;br /&gt;
&lt;br /&gt;
====== vmiop ======&lt;br /&gt;
VMIOP (Virtual Machine Input Output Plugin) handles presenting virtualized functionality into the guest.&lt;br /&gt;
&lt;br /&gt;
The Virtual Machine Input Output Plugin software handles virtual displays, compute API offload, and most importantly [https://open-iov.org/index.php/Virtual_I/O_Internals#VFIO_Quirks_(region_traps) BAR (Base Address Register) quirks].&lt;br /&gt;
&lt;br /&gt;
The VMIOP is an [[wikipedia:Software_development_kit|SDK (Software Development Kit)]] provided in binary format split between the libnvidiavgpu.so and nvidia-vgpu-mgr which provides userland helper functions for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
Messages to the VMIOP are scheduled by Linux kernel [https://www.learnlinux.org.za/courses/build/internals/ch07s02.html niceness] (scheduling abstraction).&lt;br /&gt;
&lt;br /&gt;
===== Device Firmware (GSP) =====&lt;br /&gt;
Messages received by the host RM driver (Resource Manager) are then scheduled by the RM Core contained within the GSP (GPU System Processor). The GSP handles the device's internal scheduling model.&lt;br /&gt;
&lt;br /&gt;
=== Memory Management ===&lt;br /&gt;
Managing virtual machine memory is very important to the security of virtualization.&lt;br /&gt;
&lt;br /&gt;
This section will cover the method by which secure memory &amp;quot;enclaves&amp;quot; or [https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IO Virtual Addresses (IOVAs)] may be provisioned and separation enforced by hardware constructs within the GPU.&lt;br /&gt;
&lt;br /&gt;
===== Programming the MMU =====&lt;br /&gt;
In order to hardware enforce separation between memory allocated to Virtual Machines (VMs) virtualization software must program the GPU's MMU (GMMU controller) to create IO Virtual Addresses (IOVAs).&lt;br /&gt;
&lt;br /&gt;
In order to create such configurations several abstractions are used to translate high level representations of virtualization programmed via the vmiop and gpu-mgr into practical, architecture specific instructions.&lt;br /&gt;
&lt;br /&gt;
====== AMAPLibrary ======&lt;br /&gt;
The AMAPLibrary acts as a device abstraction framework for GPU driver software to program using high level representations of MMU configuration.&lt;br /&gt;
&lt;br /&gt;
The AMAPLibrary translates high level representations of GPU virtualization into graphics architecture-specific logic contained within architecture HALs (Hardware Abstraction Layers).&lt;br /&gt;
&lt;br /&gt;
====== Architecture HALs ======&lt;br /&gt;
GPU [https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware Abstraction Layers (HALs)] contain logic specific to graphics architectures, for instance the precise method by which the GPU driver may interact with the Falcon to provision MMU protected memory.&lt;br /&gt;
&lt;br /&gt;
====== DMA from Falcon / NvRISC-V to Frame Buffer Interface (FBIF) ======&lt;br /&gt;
The Falcon (FAst Logic CONtroller) / NvRISC-V embedded controller emits DMAs to the Frame Buffer Interface (FBIF) in order to interact with the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
User programs and VMs have their memory translated through the GMMU.&lt;br /&gt;
&lt;br /&gt;
Once created memory translations within a virtual machine's IO Virtual Address (IOVA) will be protected by the device's GMMU controller.&lt;br /&gt;
&lt;br /&gt;
===== Translation Tables =====&lt;br /&gt;
&lt;br /&gt;
====== vmiop_gva ======&lt;br /&gt;
&lt;br /&gt;
=== Display Surface Virtualization ===&lt;br /&gt;
&lt;br /&gt;
== amdgpu ==&lt;br /&gt;
&lt;br /&gt;
== References (Talks &amp;amp; Reading Material) ==&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;br /&gt;
#[https://lwn.net/Articles/758903/ lwn.net: Add udmabuf misc device]&lt;br /&gt;
#[https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-v Story]&lt;br /&gt;
#[https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/04/iommu-introduction IOMMU Introduction]&lt;br /&gt;
#[https://archive.ll.mit.edu/HPEC/agendas/proc07/Day3/10_Hensley_Abstract.pdf Hardware and Compute Abstraction Layers For Accelerated Computing Using Graphics Hardware and Conventional CPUs]&lt;br /&gt;
#[https://envytools.readthedocs.io/en/latest/hw/intro.html nVidia GPU Introduction (envytools)]&lt;br /&gt;
#[https://on-demand.gputechconf.com/gtc/2014/presentations/S4725-hi-perf-graphics-nvidia-grid-virtual-gpus.pdf Delivering High Performance Remote Graphics With Nvidia GRID Virtual GPU]&lt;br /&gt;
#[https://nehajoshi.dev/post/nvidia_mig_feature/ NVIDIA Multi-Instance GPU]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Support&amp;diff=23752</id>
		<title>GPU Support</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Support&amp;diff=23752"/>
		<updated>2023-03-13T21:54:23Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Abstract ==&lt;br /&gt;
The following document will detail GPU Support for SR-IOV, SIOV, and VFIO-Mdev functionality.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Feature Matrix&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |Hardware&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; |Drivers&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |[https://openmdev.io/index.php/Virtual_IO_Internals Virtual I/O Assistance Modes]&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |Userspace&lt;br /&gt;
|-&lt;br /&gt;
!Vendor&lt;br /&gt;
!Architecture&lt;br /&gt;
!Model&lt;br /&gt;
![https://www.fsf.org/about/what-is-free-software Libre] Drivers&lt;br /&gt;
!Blob Drivers&lt;br /&gt;
![https://openmdev.io/index.php/Merged_Drivers 'Merged' Host+Guest Acceleration]&lt;br /&gt;
!Manufacturer Support&lt;br /&gt;
![https://openmdev.io/index.php/Virtual_IO_Internals#Mdev_Mode Mdev Support]&lt;br /&gt;
![https://openmdev.io/index.php/Virtual_IO_Internals#SR-IOV_Mode SR-IOV Support]&lt;br /&gt;
![https://openmdev.io/index.php/Virtual_IO_Internals#SIOV_Mode SIOV Support]&lt;br /&gt;
![https://docs.linux-gvm.org/ GVM-cli Support]&lt;br /&gt;
![https://libvf.io/ LibVF.IO Support]&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|6th Generation (Skylake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|7th Generation (Kaby Lake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|8th Generation (Coffee Lake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|9th Generation (Cannon Lake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|10th Generation (Ice Lake)&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|No&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|11th Generation (Tiger Lake)&lt;br /&gt;
|Xe*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|&lt;br /&gt;
|[https://archive.ph/0McAE#selection-4883.0-4943.35 Yes]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|12th Generation (Alder Lake)&lt;br /&gt;
|Xe*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|&lt;br /&gt;
|[https://archive.ph/0McAE#selection-4883.0-4943.35 Yes]&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Maxell&lt;br /&gt;
|*(see exceptions below)&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau], [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Pascal&lt;br /&gt;
|*&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau], [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Turing&lt;br /&gt;
|*&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau], [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Ampere&lt;br /&gt;
|A*&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau] ([https://nouveau.freedesktop.org/FeatureMatrix.html Development]), [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|No ([https://developer.nvidia.com/displaymodeselector DisplayModeSelector])&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Ampere&lt;br /&gt;
|RTX 30**&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau] ([https://nouveau.freedesktop.org/FeatureMatrix.html Development]), [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Ada Lovelace&lt;br /&gt;
|*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Hopper&lt;br /&gt;
|*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Tonga&lt;br /&gt;
|W7100&lt;br /&gt;
|AMDGPU, [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization MxGPU / GIM / GPU-IOV Module (Deprecated)]&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[[wikipedia:End-of-life_product|EOL]] (2017)&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
([https://forum.level1techs.com/t/how-to-sr-iov-mod-the-w7100-gpu/164186 patched])&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Tonga&lt;br /&gt;
|S71**&lt;br /&gt;
|AMDGPU, [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization MxGPU / GIM / GPU-IOV Module (Deprecated)]&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[[wikipedia:End-of-life_product|EOL]] (2017)&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Vega&lt;br /&gt;
|*&lt;br /&gt;
|AMDGPU&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Support#Drivers_3 Partial]&lt;br /&gt;
|Unknown&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Navi&lt;br /&gt;
|*&lt;br /&gt;
|AMDGPU&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Support#Drivers_3 Partial]&lt;br /&gt;
|Unknown&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Intel ==&lt;br /&gt;
This section will cover Mdev support on Intel GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
GPUs supporting GVT-g (software based mediation)[https://www.intel.com/content/www/us/en/support/articles/000058558/graphics.html]:&lt;br /&gt;
&lt;br /&gt;
* Intel HD Graphics 5500&lt;br /&gt;
* Intel HD Graphics 6000&lt;br /&gt;
* Intel HD Graphics 510&lt;br /&gt;
* Intel HD Graphics 520&lt;br /&gt;
* Intel HD Graphics 530&lt;br /&gt;
* Intel HD Graphics 620&lt;br /&gt;
* Intel HD Graphics 630&lt;br /&gt;
* Intel UHD Graphics 620&lt;br /&gt;
* Intel UHD Graphics 630&lt;br /&gt;
&lt;br /&gt;
GPUs supporting SR-IOV (hardware based mediation):&lt;br /&gt;
&lt;br /&gt;
* Intel Iris Xe Graphics [https://archive.ph/0McAE#selection-4883.0-4943.35][https://old.reddit.com/r/VFIO/comments/o7l2zr/sriov_on_intel_xe_graphics/]&lt;br /&gt;
* Intel Iris Xe MAX Graphics&lt;br /&gt;
&lt;br /&gt;
==== Drivers ====&lt;br /&gt;
Drivers with GVT-g support (6th - 9th gen):&lt;br /&gt;
&lt;br /&gt;
* '''[https://github.com/torvalds/linux/tree/master/drivers/gpu/drm/i915 i915 mainline]'''&lt;br /&gt;
Drivers with SR-IOV support (11th gen+):&lt;br /&gt;
* '''[https://github.com/intel/linux-intel-lts/commit/41ef979f0894326c202473807a56b599a2f3d04e i915 upstreaming]'''&lt;br /&gt;
&lt;br /&gt;
== Nvidia ==&lt;br /&gt;
This section will cover Mdev support on Nvidia GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
*All(?) Volta based GPUs (V-series)&lt;br /&gt;
*All(?) Turing based GPUs (20-series)&lt;br /&gt;
* All(?) Pascal based GPUs (10-series)&lt;br /&gt;
* Most Maxwell based GPUs (9-series) with the following notable exceptions:&lt;br /&gt;
** GTX 970 (mixed FB regions)&lt;br /&gt;
** Quadro M2000 (mixed FB regions)&lt;br /&gt;
** Tesla M40 [https://github.com/DualCoder/vgpu_unlock/issues/62]&lt;br /&gt;
&lt;br /&gt;
* NVIDIA A100 HGX 80GB&lt;br /&gt;
* NVIDIA A100 PCIe 80GB (SR-IOV: 20VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a100/pdf/PB-10577-001_v02.pdf])&lt;br /&gt;
* NVIDIA A100X&lt;br /&gt;
* NVIDIA A100 HGX 40GB&lt;br /&gt;
* NVIDIA A100 PCIe 40GB (SR-IOV: 16VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a100/pdf/A100-PCIE-Prduct-Brief.pdf])&lt;br /&gt;
* NVIDIA A40 (SR-IOV: 32VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a40/NVIDIA%20A40%20Product%20Brief.pdf])&lt;br /&gt;
* NVIDIA A30 (SR-IOV: 8VF [https://www.nvidia.com/content/dam/en-zz/Solutions/data-center/products/a30-gpu/pdf/a30-product-brief.pdf])&lt;br /&gt;
* NVIDIA A30X&lt;br /&gt;
* NVIDIA A16 (SR-IOV: 16VF [https://images.nvidia.com/content/Solutions/data-center/vgpu-a16-product-brief.pdf])&lt;br /&gt;
* NVIDIA A10 (SR-IOV: 32VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a10/pdf/A10-Product-Brief.pdf])&lt;br /&gt;
* NVIDIA A2 (SR-IOV: 16VF [https://www.nvidia.com/content/dam/en-zz/solutions/data-center/a2/pdf/a2-product-brief.pdf])&lt;br /&gt;
* NVIDIA RTX A6000&lt;br /&gt;
* NVIDIA RTX A5000&lt;br /&gt;
* Quadro RTX 8000 (SR-IOV: 24 VF [https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/quadro-product-literature/NVIDIA-Quadro-RTX-8000-PCIe-Server-Card-PB-FINAL-1219.pdf])&lt;br /&gt;
* Quadro RTX 8000 passive&lt;br /&gt;
* Quadro RTX 6000 (SR-IOV: 24 VF [https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/quadro-product-literature/NVIDIA-Quadro-RTX-6000-PCIe-Server-Card-PB-FINAL-1219.pdf])&lt;br /&gt;
* Quadro RTX 6000 passive&lt;br /&gt;
* Tesla V100&lt;br /&gt;
* Tesla T4 (SR-IOV: 16VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/tesla-t4/t4-tensor-core-product-brief.pdf])&lt;br /&gt;
* Tesla P100&lt;br /&gt;
* Tesla P40&lt;br /&gt;
* Tesla P6&lt;br /&gt;
* Tesla P4&lt;br /&gt;
* Tesla M60&lt;br /&gt;
* Tesla M10&lt;br /&gt;
* Tesla M6&lt;br /&gt;
* GRID K2 (Citrix XenServer and VMware ESXi only)&lt;br /&gt;
* GRID K1 (Citrix XenServer and VMware ESXi only)&lt;br /&gt;
&lt;br /&gt;
==== Drivers ====&lt;br /&gt;
The most widely used method of enabling Mdev functionality on Nvidia GPUs is via the use of Nvidia's proprietary driver package.&lt;br /&gt;
&lt;br /&gt;
Nvidia's proprietary Mdev driver supports both SR-IOV as well as software based mediation. The appropriate mode is chosen between the two methods based on hardware architecture.&lt;br /&gt;
&lt;br /&gt;
== AMD ==&lt;br /&gt;
This section will cover Mdev support on AMD GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
Supported GPUs:&lt;br /&gt;
&lt;br /&gt;
* AMD FirePro S7150&lt;br /&gt;
* AMD Radeon Pro V520 [https://www.amd.com/en/graphics/workstation-virtual-graphics]&lt;br /&gt;
*AMD FirePro W7100 [https://forum.level1techs.com/t/how-to-sr-iov-mod-the-w7100-gpu/164186 &amp;lt;nowiki&amp;gt;[15]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
==== Drivers ====&lt;br /&gt;
The open source [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization GIM driver] supports AMD Tonga architecture GPUs such as the FirePro S7150 &amp;amp; W7100.&lt;br /&gt;
&lt;br /&gt;
To make use of the MxGPU GIM driver on modern kernel versions you will require [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/pull/24 pull request 24].&lt;br /&gt;
&lt;br /&gt;
Virtualization driver support beyond AMD's Tonga architecture is unclear.&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Support&amp;diff=23751</id>
		<title>GPU Support</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Support&amp;diff=23751"/>
		<updated>2023-03-13T21:53:05Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Abstract ==&lt;br /&gt;
The following document will detail GPU Support for SR-IOV, SIOV, and VFIO-Mdev functionality.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Feature Matrix&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |Hardware&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; |Drivers&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |[https://openmdev.io/index.php/Virtual_IO_Internals Virtual I/O Assistance Modes]&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; |Userspace&lt;br /&gt;
|-&lt;br /&gt;
!Vendor&lt;br /&gt;
!Architecture&lt;br /&gt;
!Model&lt;br /&gt;
![https://www.fsf.org/about/what-is-free-software Libre] Drivers&lt;br /&gt;
!Blob Drivers&lt;br /&gt;
![https://openmdev.io/index.php/Merged_Drivers 'Merged' Host+Guest Acceleration]&lt;br /&gt;
!Manufacturer Support&lt;br /&gt;
![https://openmdev.io/index.php/Virtual_IO_Internals#Mdev_Mode Mdev Support]&lt;br /&gt;
![https://openmdev.io/index.php/Virtual_IO_Internals#SR-IOV_Mode SR-IOV Support]&lt;br /&gt;
![https://openmdev.io/index.php/Virtual_IO_Internals#SIOV_Mode SIOV Support]&lt;br /&gt;
![https://docs.linux-gvm.org/ GVM-cli Support]&lt;br /&gt;
![https://docs.linux-gvm.org/ GVM-mgr Support]&lt;br /&gt;
!LibGVM Support&lt;br /&gt;
![https://libvf.io/ LibVF.IO Support]&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|6th Generation (Skylake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|7th Generation (Kaby Lake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|8th Generation (Coffee Lake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|9th Generation (Cannon Lake)&lt;br /&gt;
|*HD&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|10th Generation (Ice Lake)&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|No&lt;br /&gt;
|Yes ([https://community.intel.com/t5/Graphics/Graphics-Driver-Support-Update-for-10th-Generation-and-Older/m-p/1403969/thread-id/108899 Legacy])&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|11th Generation (Tiger Lake)&lt;br /&gt;
|Xe*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|&lt;br /&gt;
|[https://archive.ph/0McAE#selection-4883.0-4943.35 Yes]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Intel&lt;br /&gt;
|12th Generation (Alder Lake)&lt;br /&gt;
|Xe*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#i915 i915]&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|&lt;br /&gt;
|[https://archive.ph/0McAE#selection-4883.0-4943.35 Yes]&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Maxell&lt;br /&gt;
|*(see exceptions below)&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau], [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Pascal&lt;br /&gt;
|*&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau], [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Turing&lt;br /&gt;
|*&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau], [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Ampere&lt;br /&gt;
|A*&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau] ([https://nouveau.freedesktop.org/FeatureMatrix.html Development]), [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|No ([https://developer.nvidia.com/displaymodeselector DisplayModeSelector])&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Ampere&lt;br /&gt;
|RTX 30**&lt;br /&gt;
|[https://nouveau.freedesktop.org/ Nouveau] ([https://nouveau.freedesktop.org/FeatureMatrix.html Development]), [https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|RM&lt;br /&gt;
|In Development&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Ada Lovelace&lt;br /&gt;
|*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|In Development&lt;br /&gt;
|-&lt;br /&gt;
|Nvidia&lt;br /&gt;
|Hopper&lt;br /&gt;
|*&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#OpenRM OpenRM]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|Yes&lt;br /&gt;
|In Development&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Tonga&lt;br /&gt;
|W7100&lt;br /&gt;
|AMDGPU, [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization MxGPU / GIM / GPU-IOV Module (Deprecated)]&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[[wikipedia:End-of-life_product|EOL]] (2017)&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
([https://forum.level1techs.com/t/how-to-sr-iov-mod-the-w7100-gpu/164186 patched])&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Tonga&lt;br /&gt;
|S71**&lt;br /&gt;
|AMDGPU, [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization MxGPU / GIM / GPU-IOV Module (Deprecated)]&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[[wikipedia:End-of-life_product|EOL]] (2017)&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Vega&lt;br /&gt;
|*&lt;br /&gt;
|AMDGPU&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Support#Drivers_3 Partial]&lt;br /&gt;
|Unknown&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|AMD&lt;br /&gt;
|Navi&lt;br /&gt;
|*&lt;br /&gt;
|AMDGPU&lt;br /&gt;
|AMDGPU-Pro&lt;br /&gt;
|No&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Support#Drivers_3 Partial]&lt;br /&gt;
|Unknown&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Intel ==&lt;br /&gt;
This section will cover Mdev support on Intel GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
GPUs supporting GVT-g (software based mediation)[https://www.intel.com/content/www/us/en/support/articles/000058558/graphics.html]:&lt;br /&gt;
&lt;br /&gt;
* Intel HD Graphics 5500&lt;br /&gt;
* Intel HD Graphics 6000&lt;br /&gt;
* Intel HD Graphics 510&lt;br /&gt;
* Intel HD Graphics 520&lt;br /&gt;
* Intel HD Graphics 530&lt;br /&gt;
* Intel HD Graphics 620&lt;br /&gt;
* Intel HD Graphics 630&lt;br /&gt;
* Intel UHD Graphics 620&lt;br /&gt;
* Intel UHD Graphics 630&lt;br /&gt;
&lt;br /&gt;
GPUs supporting SR-IOV (hardware based mediation):&lt;br /&gt;
&lt;br /&gt;
* Intel Iris Xe Graphics [https://archive.ph/0McAE#selection-4883.0-4943.35][https://old.reddit.com/r/VFIO/comments/o7l2zr/sriov_on_intel_xe_graphics/]&lt;br /&gt;
* Intel Iris Xe MAX Graphics&lt;br /&gt;
&lt;br /&gt;
==== Drivers ====&lt;br /&gt;
Drivers with GVT-g support (6th - 9th gen):&lt;br /&gt;
&lt;br /&gt;
* '''[https://github.com/torvalds/linux/tree/master/drivers/gpu/drm/i915 i915 mainline]'''&lt;br /&gt;
Drivers with SR-IOV support (11th gen+):&lt;br /&gt;
* '''[https://github.com/intel/linux-intel-lts/commit/41ef979f0894326c202473807a56b599a2f3d04e i915 upstreaming]'''&lt;br /&gt;
&lt;br /&gt;
== Nvidia ==&lt;br /&gt;
This section will cover Mdev support on Nvidia GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
*All(?) Volta based GPUs (V-series)&lt;br /&gt;
*All(?) Turing based GPUs (20-series)&lt;br /&gt;
* All(?) Pascal based GPUs (10-series)&lt;br /&gt;
* Most Maxwell based GPUs (9-series) with the following notable exceptions:&lt;br /&gt;
** GTX 970 (mixed FB regions)&lt;br /&gt;
** Quadro M2000 (mixed FB regions)&lt;br /&gt;
** Tesla M40 [https://github.com/DualCoder/vgpu_unlock/issues/62]&lt;br /&gt;
&lt;br /&gt;
* NVIDIA A100 HGX 80GB&lt;br /&gt;
* NVIDIA A100 PCIe 80GB (SR-IOV: 20VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a100/pdf/PB-10577-001_v02.pdf])&lt;br /&gt;
* NVIDIA A100X&lt;br /&gt;
* NVIDIA A100 HGX 40GB&lt;br /&gt;
* NVIDIA A100 PCIe 40GB (SR-IOV: 16VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a100/pdf/A100-PCIE-Prduct-Brief.pdf])&lt;br /&gt;
* NVIDIA A40 (SR-IOV: 32VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a40/NVIDIA%20A40%20Product%20Brief.pdf])&lt;br /&gt;
* NVIDIA A30 (SR-IOV: 8VF [https://www.nvidia.com/content/dam/en-zz/Solutions/data-center/products/a30-gpu/pdf/a30-product-brief.pdf])&lt;br /&gt;
* NVIDIA A30X&lt;br /&gt;
* NVIDIA A16 (SR-IOV: 16VF [https://images.nvidia.com/content/Solutions/data-center/vgpu-a16-product-brief.pdf])&lt;br /&gt;
* NVIDIA A10 (SR-IOV: 32VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/a10/pdf/A10-Product-Brief.pdf])&lt;br /&gt;
* NVIDIA A2 (SR-IOV: 16VF [https://www.nvidia.com/content/dam/en-zz/solutions/data-center/a2/pdf/a2-product-brief.pdf])&lt;br /&gt;
* NVIDIA RTX A6000&lt;br /&gt;
* NVIDIA RTX A5000&lt;br /&gt;
* Quadro RTX 8000 (SR-IOV: 24 VF [https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/quadro-product-literature/NVIDIA-Quadro-RTX-8000-PCIe-Server-Card-PB-FINAL-1219.pdf])&lt;br /&gt;
* Quadro RTX 8000 passive&lt;br /&gt;
* Quadro RTX 6000 (SR-IOV: 24 VF [https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/quadro-product-literature/NVIDIA-Quadro-RTX-6000-PCIe-Server-Card-PB-FINAL-1219.pdf])&lt;br /&gt;
* Quadro RTX 6000 passive&lt;br /&gt;
* Tesla V100&lt;br /&gt;
* Tesla T4 (SR-IOV: 16VF [https://www.nvidia.com/content/dam/en-zz/Solutions/Data-Center/tesla-t4/t4-tensor-core-product-brief.pdf])&lt;br /&gt;
* Tesla P100&lt;br /&gt;
* Tesla P40&lt;br /&gt;
* Tesla P6&lt;br /&gt;
* Tesla P4&lt;br /&gt;
* Tesla M60&lt;br /&gt;
* Tesla M10&lt;br /&gt;
* Tesla M6&lt;br /&gt;
* GRID K2 (Citrix XenServer and VMware ESXi only)&lt;br /&gt;
* GRID K1 (Citrix XenServer and VMware ESXi only)&lt;br /&gt;
&lt;br /&gt;
==== Drivers ====&lt;br /&gt;
The most widely used method of enabling Mdev functionality on Nvidia GPUs is via the use of Nvidia's proprietary driver package.&lt;br /&gt;
&lt;br /&gt;
Nvidia's proprietary Mdev driver supports both SR-IOV as well as software based mediation. The appropriate mode is chosen between the two methods based on hardware architecture.&lt;br /&gt;
&lt;br /&gt;
== AMD ==&lt;br /&gt;
This section will cover Mdev support on AMD GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
Supported GPUs:&lt;br /&gt;
&lt;br /&gt;
* AMD FirePro S7150&lt;br /&gt;
* AMD Radeon Pro V520 [https://www.amd.com/en/graphics/workstation-virtual-graphics]&lt;br /&gt;
*AMD FirePro W7100 [https://forum.level1techs.com/t/how-to-sr-iov-mod-the-w7100-gpu/164186 &amp;lt;nowiki&amp;gt;[15]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
==== Drivers ====&lt;br /&gt;
The open source [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization GIM driver] supports AMD Tonga architecture GPUs such as the FirePro S7150 &amp;amp; W7100.&lt;br /&gt;
&lt;br /&gt;
To make use of the MxGPU GIM driver on modern kernel versions you will require [https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/pull/24 pull request 24].&lt;br /&gt;
&lt;br /&gt;
Virtualization driver support beyond AMD's Tonga architecture is unclear.&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23750</id>
		<title>GPU Software Bill Of Materials (SBOM)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=GPU_Software_Bill_Of_Materials_(SBOM)&amp;diff=23750"/>
		<updated>2023-03-07T19:35:31Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will keep a running list of components used to achieve GPU Virtualization.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Component Table&lt;br /&gt;
!Vendor&lt;br /&gt;
!Component&lt;br /&gt;
!Description&lt;br /&gt;
!Version&lt;br /&gt;
!OSS or Blob&lt;br /&gt;
!Vendor Docs&lt;br /&gt;
!Release Date&lt;br /&gt;
!Interfaces / APIs&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Arc Compute&lt;br /&gt;
|gvm-cli&lt;br /&gt;
|Daemon&lt;br /&gt;
|1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-user OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-user docs.linux-gvm.org/gvm-user]&lt;br /&gt;
|2023.01.06&lt;br /&gt;
|CLI, [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], RMAPI, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Allocates GPU resources for use with virtualization. Registers devices and mdev callbacks with the Mediated Core.&lt;br /&gt;
|-&lt;br /&gt;
|gvm-guest&lt;br /&gt;
|Daemon&lt;br /&gt;
|0.1.0&lt;br /&gt;
|[https://github.com/Open-IOV/GVM-guest OSS]&lt;br /&gt;
|[https://docs.linux-gvm.org/gvm-guest docs.linux-gvm.org/gvm-guest]&lt;br /&gt;
|2023.02.08&lt;br /&gt;
|[https://fedoraproject.org/wiki/Features/VirtioSerial Virtio-Serial], CLI&lt;br /&gt;
|Handles IO to and from guests and the host using Virtio-Serial to handle multiple different guest modules.&lt;br /&gt;
|-&lt;br /&gt;
|Microsoft&lt;br /&gt;
|Indirect Display Driver (IDD)&lt;br /&gt;
|Driver&lt;br /&gt;
|&lt;br /&gt;
|[https://github.com/Microsoft/Windows-driver-samples/tree/main/video/IndirectDisplay OSS]&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/display/indirect-display-driver-model-overview Indirect Display Driver Overview]&lt;br /&gt;
|&lt;br /&gt;
|[https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|The Indirect Display Driver (IDD) enables GPUs to render graphics at arbitrary resolutions without a physical display connected on Windows OS systems.&lt;br /&gt;
|-&lt;br /&gt;
|RedHat&lt;br /&gt;
|vfio_pci&lt;br /&gt;
|Driver&lt;br /&gt;
|6.2-rc1&lt;br /&gt;
|[https://github.com/torvalds/linux/tree/master/drivers/vfio/pci OSS]&lt;br /&gt;
|[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough RedHat], [https://docs.kernel.org/driver-api/vfio.html kernel.org]&lt;br /&gt;
|2022.12.15&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL]&lt;br /&gt;
|Reference VFIO Stub driver used for discrete assignment of IO, and assignment of some SR-IOV-backed vGPU devices into virtual machines. This driver is commonly replaced with a vendor built VFIO interface with differing memory management and/or page pinning mechanisms which are specific to the vGPU software internals.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Intel&lt;br /&gt;
|i915 SR-IOV&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |[https://github.com/intel/linux-intel-lts/tree/5.15/ADL-linux-ER 5.15]&lt;br /&gt;
|OSS&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Intel's open source GPU driver for GuC-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GuC GuC] μOS&lt;br /&gt;
|Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|IOMMU Interrupts, Power Management Interrupts, [https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles scheduling, and power management.&lt;br /&gt;
|-&lt;br /&gt;
|HuC&lt;br /&gt;
|Firmware&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#GTT_(Graphics_Translation_Table) GTT]&lt;br /&gt;
|Handles video encoding/decoding.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#Display_Surface_Virtualization_2 Display Virtualization for Windows OS]&lt;br /&gt;
|Driver&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/releases/ 791]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS OSS]&lt;br /&gt;
|[https://github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt github.com/intel/Display-Virtualization-for-Windows-OS/blob/main/Readme.txt]&lt;br /&gt;
|&lt;br /&gt;
|udmabuf, [https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/overview-of-the-umdf UMDF], [https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/ KMDF]&lt;br /&gt;
|Intel's 'Display Virtualization for Windows OS' provides a virtual pixel surface used for hardware graphics rendering using Microsoft's open source 'Indirect Display Driver (IDD)'. Display virtualization for Windows OS makes use of display memory sharing primitives provided in-driver by the i915 host.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |Nvidia&lt;br /&gt;
|[[OpenRM]]&lt;br /&gt;
|Driver&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |525.85.12&lt;br /&gt;
|OSS&lt;br /&gt;
|[https://github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md github.com/NVIDIA/open-gpu-kernel-modules/blob/main/README.md]&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|&lt;br /&gt;
|Nvidia's open source GPU driver for GSP-equipped graphics accelerators.&lt;br /&gt;
|-&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Firmware#GSP GSP] RM (uproc)&lt;br /&gt;
|Firmware&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Blob&lt;br /&gt;
|&lt;br /&gt;
|2023.01.31&lt;br /&gt;
|RPC&lt;br /&gt;
|Embedded firmware based on LibOS containing the [https://open-iov.org/index.php/GPU_Driver_Internals#RM_Core RM Core].&lt;br /&gt;
|-&lt;br /&gt;
|Falcon/NvRISC (uproc)&lt;br /&gt;
|Firmware&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|FBIF (Frame Buffer Interface) / GMMU&lt;br /&gt;
|Embedded firmware which handles many aspects of the device including configuring the GPU's GMMU controller.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpud&lt;br /&gt;
|Daemon&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/15.0/whats-new-vgpu/index.html v15.1]&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |Blob&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |[https://docs.nvidia.com/grid/index.html docs.nvidia.com/grid]&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|Systemd, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Configures the the nvidia-vgpu-mgr process.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia-vgpu-mgr&lt;br /&gt;
|Daemon&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], RMAPI, [https://open-iov.org/index.php/GPU_Driver_Internals#Guest_kernel_(nvidia.ko) vRPC], pRPC, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware.&lt;br /&gt;
|-&lt;br /&gt;
|libnvidiavgpu.so&lt;br /&gt;
|Library&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/GPU_Driver_Internals#vmiop vmiop], RMAPI, [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles IO to and from guest RM, host RM, and hardware. Contains circular dependancies with nvidia-vgpu-mgr.&lt;br /&gt;
|-&lt;br /&gt;
|nvidia_vgpu_vfio&lt;br /&gt;
|Driver&lt;br /&gt;
|2023.01.xx&lt;br /&gt;
|[https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_DMA_Translations Type 1 IOMMU], [https://open-iov.org/index.php/Virtual_I/O_Internals#Instruction_Execution irqfd, ioeventfd], [https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/ioctl.rst IOCTL], [https://open-iov.org/index.php/Virtual_I/O_Internals#Mediated_Core Mediated Core]&lt;br /&gt;
|Handles incremental memory mapping (non-page pinning per the standard vfio-pci driver).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
# [https://riscv.org/wp-content/uploads/2016/07/Tue1100_Nvidia_RISCV_Story_V2.pdf Nvidia RISC-V Story]&lt;br /&gt;
# [https://linux-gvm.org linux-gvm.org]&lt;br /&gt;
#[https://01.org/linuxgraphics/documentation/hardware-specification-prms Intel Graphics Programmer's Reference Manuals (PRM)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2013/1/i915-hardware-contexts-and-some-bits-about-batchbuffers/ i915: Hardware Contexts (and some bits about batchbuffers)]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/the-global-gtt-part-1/ i915: The Global GTT Part 1]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/6/aliasing-ppgtt-part-2/ i915: Aliasing PPGTT Part 2]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/true-ppgtt-part-3/ i915: True PPGTT Part 3]&lt;br /&gt;
#[https://bwidawsk.net/blog/2014/7/future-ppgtt-part-4-dynamic-page-table-allocations-64-bit-address-space-gpu-mirroring-and-yeah-something-about-relocs-too/ i915: Future PPGTT Part 4 (Dynamic page table allocations, 64 bit address space, GPU &amp;quot;mirroring&amp;quot;, and yeah, something about relocs too)]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/10/graphics-part1.html i915: Security of the Intel Graphics Stack - Part 1 - Introduction]&lt;br /&gt;
#[https://igor-blue.github.io/2021/02/24/graphics-part2.html i915: Security of the Intel Graphics Stack - Part 2 - FW &amp;lt;-&amp;gt; GuC]&lt;br /&gt;
#[https://01.org/sites/default/files/documentation/an_introduction_to_intel_gvt-g_for_external.pdf i915: An Introduction to Intel GVT-g (with new architecture)]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Main_Page&amp;diff=23749</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Main_Page&amp;diff=23749"/>
		<updated>2023-03-02T00:44:47Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the '''Open-IOV''' wiki.&lt;br /&gt;
&lt;br /&gt;
== [[Articles]] ==&lt;br /&gt;
'''Visit the [[Articles|Articles page]] for an overview of this wiki's contents.'''&lt;br /&gt;
&lt;br /&gt;
New and existing projects related to the following topics are welcome:&lt;br /&gt;
&lt;br /&gt;
* '''GPU &amp;amp; IO Virtualization (VFIO / SR-IOV / SIOV / Mdev)'''&lt;br /&gt;
* '''GPU &amp;amp; IO Device Drivers'''&lt;br /&gt;
*'''Hypervisor Development'''&lt;br /&gt;
*'''Virtualization Tools'''&lt;br /&gt;
'''Signups are open''' to the public and '''anyone can contribute'''.&lt;br /&gt;
&lt;br /&gt;
== Community ==&lt;br /&gt;
'''Discord:''' https://discord.gg/Rb9K9DYxKK&lt;br /&gt;
&lt;br /&gt;
'''IRC:''' #gvm &amp;amp; #gvm-devel on oftc.net&lt;br /&gt;
&lt;br /&gt;
== Contributing to Open-IOV.org ==&lt;br /&gt;
Due to spam account creation is temporarily disabled through the Open-IOV website.&lt;br /&gt;
&lt;br /&gt;
Contact Open-IOV moderators in the community '''#Documentation''' channel to have your account allowlisted until unmoderated signups re-open.&lt;br /&gt;
&lt;br /&gt;
== Creating an Article ==&lt;br /&gt;
If you'd like to start a new article or contribute to an existing one simply create an account then visit a URL containing the article title you'd like to create or edit and click the &amp;quot;Edit&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
https://open-iov.org/index.php/your-article-title-here&lt;br /&gt;
&lt;br /&gt;
New articles should be linked on the [[Articles|Articles page]] so people can find them.&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23748</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23748"/>
		<updated>2023-03-02T00:36:30Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Open-IOV:About About Open-IOV (CC-BY-4.0)]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== GVM Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM &amp;lt;nowiki&amp;gt;GVM [Nvidia Open Kernel Modules]&amp;lt;/nowiki&amp;gt;] &amp;lt;sup&amp;gt;(support documentation up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU &amp;lt;nowiki&amp;gt;GVM [AMDGPU]&amp;lt;/nowiki&amp;gt;]  &amp;lt;sup&amp;gt;(support documentation not up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://linux-gvm.org/ GPU Virtual Machine (GVM)]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[[Intel SR-IOV APIs|i915 SR-IOV API]]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23747</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23747"/>
		<updated>2023-03-02T00:34:34Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== GVM Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM &amp;lt;nowiki&amp;gt;GVM [Nvidia Open Kernel Modules]&amp;lt;/nowiki&amp;gt;] &amp;lt;sup&amp;gt;(support documentation up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU &amp;lt;nowiki&amp;gt;GVM [AMDGPU]&amp;lt;/nowiki&amp;gt;]  &amp;lt;sup&amp;gt;(support documentation not up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://linux-gvm.org/ GPU Virtual Machine (GVM)]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[[Intel SR-IOV APIs|i915 SR-IOV API]]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=AMDGPU&amp;diff=23746</id>
		<title>AMDGPU</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=AMDGPU&amp;diff=23746"/>
		<updated>2023-03-02T00:32:45Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The AMDGPU driver is AMD's open source GPU driver which comes included with the Linux kernel.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;This software's source code can be viewed [https://github.com/torvalds/linux/tree/master/drivers/gpu/drm/amd/amdgpu here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This OpenMdev page should aim to provide similar insights about APIs exposed to Linux developers to those documented on the [https://openmdev.io/index.php/OpenRM OpenRM Driver API] page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page may provide some of the required information from which details immediately relevant to graphics mediation can be consolidated:&lt;br /&gt;
&lt;br /&gt;
https://dri.freedesktop.org/docs/drm/gpu/amdgpu.html&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=Articles&amp;diff=23745</id>
		<title>Articles</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Articles&amp;diff=23745"/>
		<updated>2023-03-02T00:32:18Z</updated>

		<summary type="html">&lt;p&gt;Arthur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page indexes the articles contained within Open-IOV.&lt;br /&gt;
&lt;br /&gt;
If you're new to GPU Virtualization start by reading the '''[[Introduction]]''' article.&amp;lt;blockquote&amp;gt;An absence of critical technical documentation has historically slowed growth and adoption of developer ecosystems for GPU virtualization.&lt;br /&gt;
&lt;br /&gt;
This [https://creativecommons.org/licenses/by/4.0/ CC-BY-4.0] licensed content can either be used with attribution, or used as inspiration for new documentation, created by GPU vendors for public commercial distribution as developer documentation.&lt;br /&gt;
&lt;br /&gt;
Where possible, this documentation will clearly label dates and versions of observed-but-not-guaranteed behaviour vs. vendor-documented stable interfaces/behaviour with guarantees of forward or backward compatibility.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start Here ===&lt;br /&gt;
[[Introduction]]&lt;br /&gt;
&lt;br /&gt;
===Abstract===&lt;br /&gt;
[[Introductory Concepts &amp;amp; Definitions|Glossary]]&lt;br /&gt;
&lt;br /&gt;
[[Virtualization Fundamentals]]&lt;br /&gt;
&lt;br /&gt;
[[Merged Drivers]]&lt;br /&gt;
&lt;br /&gt;
=== Design Documents ===&lt;br /&gt;
[[Virtual IO Internals|Virtual I/O Internals]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Driver Internals]]&lt;br /&gt;
=== GVM Integration Documents ===&lt;br /&gt;
[https://open-iov.org/index.php/OpenRM &amp;lt;nowiki&amp;gt;GVM [Nvidia Open Kernel Modules]&amp;lt;/nowiki&amp;gt;] &amp;lt;sup&amp;gt;(support documentation up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/AMDGPU &amp;lt;nowiki&amp;gt;GVM [AMDGPU]&amp;lt;/nowiki&amp;gt;]  &amp;lt;sup&amp;gt;(support documentation not up-to-date)&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Projects===&lt;br /&gt;
[https://linux-gvm.org/ GPU Virtual Machine (GVM)]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LibVF.IO LibVF.IO]&lt;br /&gt;
&lt;br /&gt;
[[Hyperborea]]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/LIME_Is_Mediated_Emulation LIME Is Mediated Emulation]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/Looking_Glass_KVMFR Looking Glass]&lt;br /&gt;
&lt;br /&gt;
[https://openxt.atlassian.net/wiki/spaces/OD/pages/10747915/What+is+OpenXT OpenXT]&lt;br /&gt;
&lt;br /&gt;
[https://gitlab.com/vglass OpenXT: vGlass]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenXT/surfman OpenXT: Surfman (legacy DRM)]&lt;br /&gt;
&lt;br /&gt;
[https://www.bromium.com/opensource/ Bromium/uXen]&lt;br /&gt;
&lt;br /&gt;
[https://xenproject.org/help/documentation/ Xen Project]&lt;br /&gt;
&lt;br /&gt;
[https://www.qubes-os.org/doc/ Qubes OS]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/tutorials/using_celadon_as_uos.html Intel Celadon]&lt;br /&gt;
&lt;br /&gt;
[https://open-iov.org/index.php/VGPU_Unlock vGPU_Unlock]&lt;br /&gt;
&lt;br /&gt;
[[LibRM]]&lt;br /&gt;
=== Device Support===&lt;br /&gt;
[[GPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[CPU Support]]&lt;br /&gt;
&lt;br /&gt;
[[GPU Firmware]]&lt;br /&gt;
&lt;br /&gt;
=== Software Support ===&lt;br /&gt;
[https://open-iov.org/index.php/Hypervisor_Support Hypervisor Support]&lt;br /&gt;
&lt;br /&gt;
[[GPU Software Bill Of Materials (SBOM)]]&lt;br /&gt;
&lt;br /&gt;
=== API Documentation ===&lt;br /&gt;
&lt;br /&gt;
==== Kernel APIs ====&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api Kernel.org Driver Core Documentation]&lt;br /&gt;
&lt;br /&gt;
[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/iommu-based-gpu-isolation NT Kernel (Windows) IOMMU-based GPU Isolation]&lt;br /&gt;
&lt;br /&gt;
[https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/vfio.rst VFIO] - [https://github.com/torvalds/linux/blob/master/include/uapi/linux/vfio.h vfio.h] - [https://elixir.bootlin.com/linux/latest/source/include/linux/mdev.h mdev.h]&lt;br /&gt;
&lt;br /&gt;
[https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/tree/Documentation/driver-api/vfio-mediated-device.rst?h=driver-core-next&amp;amp;id=7de3697e9cbd4bd3d62bafa249d57990e1b8f294 VFIO Mediated Device]&lt;br /&gt;
==== Driver APIs ====&lt;br /&gt;
[[Intel SR-IOV APIs|i915 SR-IOV API]]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/api/GVT-g_api.html i915 GVT-g API]&lt;br /&gt;
&lt;br /&gt;
[https://nouveau.freedesktop.org/Development.html Nouveau Tools &amp;amp; API]&lt;br /&gt;
==== Sample Code ====&lt;br /&gt;
GPLv2 sources mirrored from [https://elixir.bootlin.com/linux/latest/source/samples/vfio-mdev/ elixir.bootlin.com] with [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/Makefile simple makefile changes].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mtty.c mtty.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy.c mdpy.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-fb.c mdpy-fb.c] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mdpy-defs.h mdpy-defs.h] - [https://github.com/OpenMdev/VFIO-Mdev_Samples/blob/master/mbochs.c mbochs.c]&lt;br /&gt;
&lt;br /&gt;
==== Virtualization APIs ====&lt;br /&gt;
[https://open-iov.org/index.php/Mdev-GPU#Mdev-CLI GVM/Mdev-CLI API]&lt;br /&gt;
&lt;br /&gt;
[https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html QEMU Machine Protocol (QMP) Reference Manual]&lt;br /&gt;
&lt;br /&gt;
[https://projectacrn.github.io/2.1/developer-guides/hld/ivshmem-hld.html Inter-VM Shared Memory (IVSHMEM)]&lt;br /&gt;
===User Guides===&lt;br /&gt;
[https://arccompute.com/blog/libvfio-commodity-gpu-multiplexing/ LibVF.IO Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://looking-glass.io/docs/stable/ Looking Glass Quickstart Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide Intel GVT-g Setup Guide]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/GPUOpen-LibrariesAndSDKs/MxGPU-Virtualization/tree/master/docs AMD GPU-IOV Module Docs]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF PCI passthrough via OVMF]&lt;br /&gt;
&lt;br /&gt;
[https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/index RedHat Virtualization Guide]&lt;br /&gt;
&lt;br /&gt;
=== Developer Guides ===&lt;br /&gt;
[https://rayanfam.com/tags/hypervisor/ Hypervisor From Scratch]&lt;br /&gt;
&lt;br /&gt;
[https://lwn.net/Kernel/LDD3/ Linux Device Drivers (3rd Edition)]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/gpu/ GPU Driver Developer's Guide]&lt;br /&gt;
&lt;br /&gt;
[https://dri.freedesktop.org/docs/drm/PCI/pci.html# How To Write PCI Drivers]&lt;br /&gt;
&lt;br /&gt;
[https://doc.dpdk.org/guides-16.04/prog_guide/ivshmem_lib.html Data Plane Development Kit: IVSHMEM Programming Guide]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs Hyper-V Hypervisor Top Level Functional Specification (TLFS)]&lt;br /&gt;
&lt;br /&gt;
=== Communities &amp;amp; Mailing Lists ===&lt;br /&gt;
[https://discord.gg/Rb9K9DYxKK Open-IOV Discord]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/intel-gfx Intel-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/nouveau Nouveau Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://lists.freedesktop.org/mailman/listinfo/amd-gfx AMD-gfx Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://listman.redhat.com/mailman/listinfo/vfio-users VFIO-users Mailing List]&lt;br /&gt;
&lt;br /&gt;
[https://forum.level1techs.com/c/software/vfio/132 &amp;lt;nowiki&amp;gt;Level1Techs Forum [VFIO Topic]&amp;lt;/nowiki&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
[https://old.reddit.com/r/VFIO/ VFIO Subreddit]&lt;/div&gt;</summary>
		<author><name>Arthur</name></author>
	</entry>
</feed>