blob: 0a0da1a40986ee8a31fc81ca5a71a45e6935ec4f (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
package org.openslx.runvirt.plugin.qemu.configuration;
import org.openslx.libvirt.capabilities.Capabilities;
import org.openslx.libvirt.domain.Domain;
import org.openslx.libvirt.domain.device.Hostdev;
import org.openslx.libvirt.domain.device.HostdevMdev;
import org.openslx.libvirt.domain.device.HostdevMdev.Model;
import org.openslx.libvirt.domain.device.HostdevMdevDeviceAddress;
import org.openslx.libvirt.domain.device.Video;
import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs;
import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu;
import org.openslx.runvirt.virtualization.LibvirtHypervisorException;
import org.openslx.virtualization.configuration.transformation.TransformationException;
import org.openslx.virtualization.configuration.transformation.TransformationSpecific;
/**
* Specific Intel mediated device (Intel GVT-g) passthrough transformation for Libvirt/QEMU
* virtualization configurations.
*
* @author Manuel Bentele
* @version 1.0
*/
public class TransformationSpecificQemuMdevPassthroughIntel
extends TransformationSpecific<Domain, CommandLineArgs, LibvirtHypervisorQemu>
{
/**
* Name of the configuration transformation.
*/
private static final String NAME = "QEMU mediated device passthrough [Intel]";
/**
* Creates a new Intel mediated device passthrough transformation for Libvirt/QEMU virtualization
* configurations.
*
* @param hypervisor Libvirt/QEMU hypervisor.
*/
public TransformationSpecificQemuMdevPassthroughIntel( LibvirtHypervisorQemu hypervisor )
{
super( TransformationSpecificQemuMdevPassthroughIntel.NAME, hypervisor );
}
/**
* Validates a virtualization configuration and input arguments for this transformation.
*
* @param config virtualization configuration for the validation.
* @param args input arguments for the validation.
* @throws TransformationException validation has failed.
*/
private void validateInputs( Domain config, CommandLineArgs args ) throws TransformationException
{
if ( config == null || args == null ) {
throw new TransformationException( "Virtualization configuration or input arguments are missing!" );
}
}
/**
* Queries and returns the capabilities of the Libvirt/QEMU hypervisor.
*
* @return capabilities of the Libvirt/QEMU hypervisor.
* @throws TransformationException failed to query and return the capabilities of the
* Libvirt/QEMU hypervisor.
*/
protected Capabilities getCapabilities() throws TransformationException
{
Capabilities capabilities = null;
try {
capabilities = this.getVirtualizer().getCapabilites();
} catch ( LibvirtHypervisorException e ) {
final String errorMsg = new String(
"Failed to retrieve host capabilities from QEMU virtualizer: " + e.getLocalizedMessage() );
throw new TransformationException( errorMsg );
}
return capabilities;
}
@Override
public void transform( Domain config, CommandLineArgs args ) throws TransformationException
{
// validate configuration and input arguments
this.validateInputs( config, args );
// check if passthrough of an Intel mediated device (virtual GPU) takes place
if ( args.isIntelMdevPassthroughEnabled() ) {
// validate submitted mediated device UUID
final HostdevMdevDeviceAddress mdevDeviceAddress = HostdevMdevDeviceAddress.valueOf( args.getVmIlMdevId0() );
if ( mdevDeviceAddress == null ) {
final String errorMsg = "UUID of the Intel mediated device (virtual GPU) address is invalid!";
throw new TransformationException( errorMsg );
}
// check if IOMMU support is available on the host
if ( !this.getCapabilities().hasHostIommuSupport() ) {
final String errorMsg = "IOMMU support is not available on the hypervisor but required for Intel mediated device (virtual GPU) passthrough!";
throw new TransformationException( errorMsg );
}
// remove all existing hostdev devices
// otherwise the Intel specific QEMU options with index 0 do not work
for ( final Hostdev hostdevDevice : config.getHostdevDevices() ) {
hostdevDevice.remove();
}
// passthrough Intel mediated device (virtual GPU)
final HostdevMdev mdevDevice = config.addHostdevMdevDevice();
mdevDevice.setManaged( false );
mdevDevice.setModel( Model.VFIO_PCI );
mdevDevice.setDisplayOn( true );
mdevDevice.setMemoryFramebufferOn( true );
mdevDevice.setSource( mdevDeviceAddress );
// set Intel specific QEMU options that are not handeled by Libvirt yet
config.addQemuCmdlnArgument( "-set" );
config.addQemuCmdlnArgument( "device.hostdev0.x-igd-opregion=on" );
config.addQemuCmdlnArgument( "-set" );
config.addQemuCmdlnArgument( "device.hostdev0.driver=vfio-pci-nohotplug" );
// disable all software video devices by disable them
for ( Video videoDevice : config.getVideoDevices() ) {
videoDevice.disable();
}
}
}
}
|