summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Bentele2021-08-23 12:00:17 +0200
committerManuel Bentele2021-08-23 12:00:17 +0200
commit5f9ff0a607985298e1a51f45f37110d88466ec3b (patch)
treee09908d2696d4e7b5f36ade9ccabe9c303c868b9
parent[qemu] Replace spaces with tabs in PCI passthrough include (diff)
downloadmltk-5f9ff0a607985298e1a51f45f37110d88466ec3b.tar.gz
mltk-5f9ff0a607985298e1a51f45f37110d88466ec3b.tar.xz
mltk-5f9ff0a607985298e1a51f45f37110d88466ec3b.zip
[qemu] Add setup of a global Intel GVT-g instance if GVT-g is enabled
-rwxr-xr-xcore/modules/qemu/data/opt/openslx/scripts/systemd-qemu_env43
-rw-r--r--core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/includes/passthrough-mdev.inc163
-rw-r--r--core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include6
3 files changed, 212 insertions, 0 deletions
diff --git a/core/modules/qemu/data/opt/openslx/scripts/systemd-qemu_env b/core/modules/qemu/data/opt/openslx/scripts/systemd-qemu_env
index b71919de..ffa54ce1 100755
--- a/core/modules/qemu/data/opt/openslx/scripts/systemd-qemu_env
+++ b/core/modules/qemu/data/opt/openslx/scripts/systemd-qemu_env
@@ -44,3 +44,46 @@ if [ ! -e /dev/kvm ]; then
slxlog "qemu" "/dev/kvm not found! Missing kvm kernel module(s)?"
exit 1
fi
+
+#
+# create and setup Intel GVT-g mediated device instance for passthrough if Intel GVT-g is enabled
+#
+source /opt/openslx/vmchooser/plugins/qemukvm/includes/kernel-cmdln.inc
+source /opt/openslx/vmchooser/plugins/qemukvm/includes/passthrough-mdev.inc
+
+if passthrough_mdev_enabled; then
+ # check if passthrough is configured properly
+ if ! passthrough_mdev_check; then
+ slxlog "qemu" "mediated device passthrough is enabled but not setup properly!"
+ exit 2;
+ fi
+
+ # load required kernel modules for mediated device passthrough
+ modprobe "vfio-mdev" || { slxlog "qemu" "Could not load 'vfio-mdev' kernel modul!"; exit 3; }
+ modprobe "kvmgt" || { slxlog "qemu" "Could not load 'kvmgt' kernel modul!"; exit 4; }
+
+ # get Intel integrated GPU mediated device for passthrough
+ local pt_mdev_device="$(passthrough_mdev_device_get_intel_igd)"
+ if [ -z "${pt_mdev_device}" ]; then
+ slxlog "qemu" "Could find any Intel integrated GPU with mediated device (Intel GVT-g) support!"
+ exit 5;
+ fi
+
+ # get Intel GVT-g mediated device instance type
+ local pt_mdev_device_type="$(passthrough_mdev_type_get "${pt_mdev_device}")"
+ if [ -z "${pt_mdev_device_type}" ]; then
+ slxlog "qemu" "Could obtain the mediated device instance type of the Intel integrated GPU (${pt_mdev_device})"
+ exit 6;
+ fi
+
+ # generate UUID for Intel GVT-g mediated device instance
+ local pt_mdev_uuid="$(uuidgen)"
+
+ # create Intel GVT-g mediated device instance
+ passthrough_mdev_instance_create "${pt_mdev_device}" "${pt_mdev_device_type}" "${pt_mdev_uuid}"
+ if [ "${?}" -eq 0 ]; then
+ slxlog "qemu" "Successfully created Intel GVT-g mediated device instance (${pt_mdev_uuid})"
+ else
+ slxlog "qemu" "Failed to create Intel GVT-g mediated device instance!"
+ fi
+fi
diff --git a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/includes/passthrough-mdev.inc b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/includes/passthrough-mdev.inc
new file mode 100644
index 00000000..067cc35d
--- /dev/null
+++ b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/includes/passthrough-mdev.inc
@@ -0,0 +1,163 @@
+# -----------------------------------------------------------------------------
+#
+# Copyright (c) 2009..2021 bwLehrpool-Projektteam
+#
+# This program/file is free software distributed under the GPL version 2.
+# See https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# If you have any feedback please consult https://bwlehrpool.de and
+# send your feedback to support@bwlehrpool.de.
+#
+# General information about bwLehrpool can be found at https://bwlehrpool.de
+#
+# -----------------------------------------------------------------------------
+# Utils and functions to setup mediated device passthrough (Intel GVT-g)
+# -----------------------------------------------------------------------------
+
+# Function to get state of passthrough
+# Return : 0 (true) if passthrough is enabled, otherwise 1 (false)
+function passthrough_mdev_enabled() {
+ local passthrough_iommu="$(kernel_cmdln_parse_option "iommu")"
+ local intel_gvt="$(kernel_cmdln_parse_option "i915.enable_gvt")"
+ if [ "${passthrough_iommu}" == "pt" ] && [ "${intel_gvt}" -eq 1 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# Function to check validitiy of the passthrough configuration
+# Return : 0 (true) if passthrough is configured properly, otherwise 1 (false)
+function passthrough_mdev_check() {
+ local passthrough_iommu_intel="$(kernel_cmdln_parse_option "intel_iommu")"
+ local passthrough_iommu_amd="$(kernel_cmdln_parse_option "amd_iommu")"
+ if [ "${passthrough_iommu_intel}" != "on" ] && [ "${passthrough_iommu_amd}" != "on" ]; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+# Function to list all physical devices that support mediated device passthrough
+# Return : list of PCI addresses from devices that support mediated device passthrough
+function passthrough_mdev_devices() {
+ mdevctl types --dumpjson | jq -r ".[] | keys | .[]"
+}
+
+# Function to check if a physical device, that supports mediated device passthrough, is an Intel integrated GPU
+# Parameter 1: PCI address of the physical device that supports mediated device passthrough
+# Return : 0 (true) if physical device is an Intel integrated GPU, otherwise 1 (false)
+function passthrough_mdev_device_is_intel_igd() {
+ local pt_mdev_device_pci_info="$(lspci -vmm -n -s "${1}")"
+ local pt_mdev_device_pci_vendor="$(awk '$1 = /^Vendor:/ {print $2}' <<< "${pt_mdev_device_pci_info}")"
+ local pt_mdev_device_pci_class="$(awk '$1 = /^Class:/ {print $2}' <<< "${pt_mdev_device_pci_info}")"
+ if [ "${pt_mdev_device_pci_vendor}" = "8086" ] && [ "${pt_mdev_device_pci_class}" = "0300" ]; then
+ return 0;
+ else
+ return 1;
+ fi
+}
+
+# Function to get the first physical device that supports mediated device passthrough and is an Intel integrated GPU
+# Return : PCI address of the physical device that supports mediated device passthrough and is an Intel integrated GPU
+function passthrough_mdev_device_get_intel_igd() {
+ local pt_mdev_devices_addresses=($(passthrough_mdev_devices))
+ for pt_mdev_device_address in ${pt_mdev_devices_addresses[@]}; do
+ # check if device is an Intel integrated GPU
+ if passthrough_mdev_device_is_intel_igd "${pt_mdev_device_address}"; then
+ echo "${pt_mdev_device_address}"
+ return 0;
+ fi
+ done
+
+ return 1;
+}
+
+# Function to list all mediated device instance types of a specified physical device
+# Parameter 1: PCI address of the physical device that supports mediated device passthrough
+# Return : list of mediated device instance types supported by the specified physical device
+function passthrough_mdev_types() {
+ mdevctl types --dumpjson | jq -r ".[] | .\"${1}\" | .[] | keys | .[]"
+}
+
+# Function to get the first mediated device instance type of a specified physical device
+# Parameter 1: PCI address of the physical device that supports mediated device passthrough
+# Return : first mediated device instance type supported by the specified physical device
+function passthrough_mdev_type_get() {
+ local pt_mdev_device_types=($(passthrough_mdev_types "${1}"))
+ if [ "${#pt_mdev_device_types[@]}" -gt 0 ]; then
+ echo "${pt_mdev_device_types[0]}"
+ return 0;
+ else
+ return 1;
+ fi
+}
+
+# Function to get the description of a specified mediated device instance type
+# Parameter 1: PCI address of the physical device that supports mediated device passthrough
+# Parameter 2: mediated device instance type supported by the specified physical device
+# Return : description of the mediated device instance type supported by the specified physical device
+function passthrough_mdev_type_description() {
+ mdevctl types --dumpjson | jq -r ".[] | .\"${1}\" | .[] | select(.\"${2}\") | .[] | .\"description\""
+}
+
+# Function to get the available instance count of a specified mediated device instance type
+# Parameter 1: PCI address of the physical device that supports mediated device passthrough
+# Parameter 2: mediated device instance type supported by the specified physical device
+# Return : available instances of the mediated device instance type supported by the specified physical device
+function passthrough_mdev_type_num_instances() {
+ mdevctl types --dumpjson | jq -r ".[] | .\"${1}\" | .[] | select(.\"${2}\") | .[] | .\"available_instances\""
+}
+
+# Function to create a new mediated device instance
+# Parameter 1: PCI address of the physical device that supports mediated device passthrough
+# Parameter 2: mediated device instance type supported by the specified physical device
+# Parameter 3: UUID for the created mediated device instance
+function passthrough_mdev_instance_create() {
+ mdevctl start --parent "${1}" --type "${2}" --uuid "${3}"
+}
+
+# Function to delete an existing mediated device instance
+# Parameter 1: UUID of the existing mediated device instance
+function passthrough_mdev_instance_delete() {
+ mdevctl stop --uuid "${1}"
+}
+
+# Function to obtain mediated device UUID of a globally created mediated device (Intel GVT-g) instance for passthrough
+# Return : mediated device UUID of a globally created mediated device (Intel GVT-g) instance
+function passthrough_mdev_instance_get() {
+ local passthrough_mdev_instances=($(mdevctl list | cut -d ' ' -f 1))
+ if [ "${#passthrough_mdev_instances[@]}" -eq 1 ]; then
+ echo "${passthrough_mdev_instances[0]}"
+ return 0;
+ else
+ return 1;
+ fi
+}
+
+# Function to setup mediated device passthrough
+# Return : mediated device ID of the specified and configured mediated device (Intel GVT-g instance) for passthrough
+function passthrough_mdev_setup() {
+ # check if passthrough is enabled
+ if passthrough_mdev_enabled; then
+ # check if passthrough is configured properly
+ if ! passthrough_mdev_check; then
+ return 1;
+ fi
+
+ writelog "Passthrough of mediated devices (mdev) is enabled successfully"
+
+ # obtain created mediated device for passthrough
+ local pt_gpu_mdev_id="$(passthrough_mdev_instance_get)"
+
+ # check if mediated device ID could be obtained
+ if [ -z "${pt_gpu_mdev_id}" ]; then
+ writelog "Failed to obtain created mediated device UUID"
+ return 2;
+ fi
+
+ echo "${pt_gpu_mdev_id}"
+ fi
+
+ return 0;
+}
diff --git a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include
index e497dda2..12239b4e 100644
--- a/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include
+++ b/core/modules/qemu/data/opt/openslx/vmchooser/plugins/qemukvm/run-virt.include
@@ -27,6 +27,8 @@ run_plugin() {
$(safesource "${QEMU_INCLUDE_DIR}/kernel-cmdln.inc")
# include PCI passthrough utils and functions
$(safesource "${QEMU_INCLUDE_DIR}/passthrough-pci.inc")
+ # include mediated device passthrough utils and functions
+ $(safesource "${QEMU_INCLUDE_DIR}/passthrough-mdev.inc")
# setup RW image access for operation
local vm_diskfile
@@ -43,6 +45,9 @@ run_plugin() {
# setup GPU passthrough and obtain PCI addresses and IDs if passthrough is enabled
local pt_gpu_pci_ids=($(passthrough_pci_setup))
+ # setup GPU mediated device passthrough and obtain mediated device address
+ local pt_gpu_mdev_id=($(passthrough_mdev_setup))
+
# write finalized config in debug mode to temporary folder for debugging purposes
if [ "${DEBUG}" = "true" ]; then
local vm_final_config="/tmp/qemu-last-config.xml"
@@ -69,6 +74,7 @@ run_plugin() {
notempty CDROM_1 && VIRTCMDOPTS+=( "-vmcdrom1" "${CDROM_1}" )
notempty SERIAL0 && VIRTCMDOPTS+=( "-vmserial0" "${SERIAL0}" )
notempty PARALLEL0 && VIRTCMDOPTS+=( "-vmparallel0" "${PARALLEL0}" )
+ notempty pt_gpu_mdev_id && VIRTCMDOPTS+=( "-vmilmdevid0" "${pt_gpu_mdev_id}" )
if [ "${SHARE_REMAP_MODE}" -gt 1 ]; then
notempty HOME_SHARE_PATH && VIRTCMDOPTS+=( "-vmfssrc0" "${HOME_SHARE_PATH}" )