Skip to content

Commit 457806e

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "libvirt: Add vIOMMU device to guest"
2 parents 8b55b44 + 14e3b35 commit 457806e

File tree

17 files changed

+801
-144
lines changed

17 files changed

+801
-144
lines changed

doc/notification_samples/common_payloads/ImageMetaPropsPayload.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"hw_architecture": "x86_64"
55
},
66
"nova_object.name": "ImageMetaPropsPayload",
7-
"nova_object.version": "1.11"
7+
"nova_object.version": "1.12"
88
}

doc/source/admin/pci-passthrough.rst

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,61 @@ the PF and its VFs are made available for consumption.
429429

430430

431431
For deeper technical details please read the `nova specification. <https://specs.openstack.org/openstack/nova-specs/specs/zed/approved/pci-device-tracking-in-placement.html>`_
432+
433+
434+
Virtual IOMMU support
435+
---------------------
436+
437+
With provided :nova:extra-spec:`hw:viommu_model` flavor extra spec or equivalent
438+
image metadata property ``hw_viommu_model`` and with the guest CPU architecture
439+
and OS allows, we can enable vIOMMU in libvirt driver.
440+
441+
.. note::
442+
443+
Enable vIOMMU might introduce significant performance overhead.
444+
You can see performance comparision table from
445+
`AMD vIOMMU session on KVM Forum 2021`_.
446+
For the above reason, vIOMMU should only be enabled for workflow that
447+
require it.
448+
449+
.. _`AMD vIOMMU session on KVM Forum 2021`: https://static.sched.com/hosted_files/kvmforum2021/da/vIOMMU%20KVM%20Forum%202021%20-%20v4.pdf
450+
451+
Here are four possible values allowed for ``hw:viommu_model``
452+
(and ``hw_viommu_model``):
453+
454+
**virtio**
455+
Supported on Libvirt since 8.3.0, for Q35 and ARM virt guests.
456+
457+
**smmuv3**
458+
Supported on Libvirt since 5.5.0, for ARM virt guests.
459+
**intel**
460+
Supported for for Q35 guests.
461+
462+
**auto**
463+
This option will translate to ``virtio`` if Libvirt supported,
464+
else ``intel`` on X86 (Q35) and ``smmuv3`` on AArch64.
465+
466+
For the viommu attributes:
467+
468+
* ``intremap``, ``caching_mode``, and ``iotlb``
469+
options for viommu (These attributes are driver attributes defined in
470+
`Libvirt IOMMU Domain`_) will direcly enabled.
471+
472+
* ``eim`` will directly enabled if machine type is Q35.
473+
``eim`` is driver attribute defined in `Libvirt IOMMU Domain`_.
474+
475+
.. note::
476+
477+
eim(Extended Interrupt Mode) attribute (with possible values on and off)
478+
can be used to configure Extended Interrupt Mode.
479+
A q35 domain with split I/O APIC (as described in hypervisor features),
480+
and both interrupt remapping and EIM turned on for the IOMMU, will be
481+
able to use more than 255 vCPUs. Since 3.4.0 (QEMU/KVM only).
482+
483+
* ``aw_bits`` attribute can used to set the address width to allow mapping
484+
larger iova addresses in the guest. Since Qemu current supported
485+
values are 39 and 48, we directly set this to larger width (48)
486+
if Libvirt supported.
487+
``aw_bits`` is driver attribute defined in `Libvirt IOMMU Domain`_.
488+
489+
.. _`Libvirt IOMMU Domain`: https://libvirt.org/formatdomain.html#iommu-devices

nova/api/validation/extra_specs/hw.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,22 @@
511511
],
512512
},
513513
),
514+
base.ExtraSpecValidator(
515+
name='hw:viommu_model',
516+
description=(
517+
'This can be used to set model for virtual IOMMU device.'
518+
),
519+
value={
520+
'type': str,
521+
'enum': [
522+
'intel',
523+
'smmuv3',
524+
'virtio',
525+
'auto'
526+
],
527+
'description': 'model for vIOMMU',
528+
},
529+
),
514530
]
515531

516532
ephemeral_encryption_validators = [

nova/exception.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,16 @@ class Invalid(NovaException):
207207
code = 400
208208

209209

210+
class InvalidVIOMMUMachineType(Invalid):
211+
msg_fmt = _("vIOMMU is not supported by Current machine type %(mtype)s "
212+
"(Architecture: %(arch)s).")
213+
214+
215+
class InvalidVIOMMUArchitecture(Invalid):
216+
msg_fmt = _("vIOMMU required either x86 or AArch64 architecture, "
217+
"but given architecture %(arch)s.")
218+
219+
210220
class InvalidConfiguration(Invalid):
211221
msg_fmt = _("Configuration is Invalid.")
212222

nova/notifications/objects/image.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ class ImageMetaPropsPayload(base.NotificationPayloadBase):
129129
# Version 1.10: Added 'hw_ephemeral_encryption' and
130130
# 'hw_ephemeral_encryption_format' fields
131131
# Version 1.11: Added 'hw_locked_memory' field
132-
VERSION = '1.11'
132+
# Version 1.12: Added 'hw_viommu_model' field
133+
VERSION = '1.12'
133134

134135
SCHEMA = {
135136
k: ('image_meta_props', k) for k in image_meta.ImageMetaProps.fields}

nova/objects/fields.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,16 @@ def coerce(self, obj, attr, value):
616616
return super(VIFModel, self).coerce(obj, attr, value)
617617

618618

619+
class VIOMMUModel(BaseNovaEnum):
620+
621+
INTEL = 'intel'
622+
SMMUV3 = 'smmuv3'
623+
VIRTIO = 'virtio'
624+
AUTO = 'auto'
625+
626+
ALL = (INTEL, SMMUV3, VIRTIO, AUTO)
627+
628+
619629
class VMMode(BaseNovaEnum):
620630
"""Represents possible vm modes for instances.
621631
@@ -1301,6 +1311,10 @@ class VIFModelField(BaseEnumField):
13011311
AUTO_TYPE = VIFModel()
13021312

13031313

1314+
class VIOMMUModelField(BaseEnumField):
1315+
AUTO_TYPE = VIOMMUModel()
1316+
1317+
13041318
class VMModeField(BaseEnumField):
13051319
AUTO_TYPE = VMMode()
13061320

nova/objects/image_meta.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,17 @@ class ImageMetaProps(base.NovaObject):
191191
# Version 1.32: Added 'hw_ephemeral_encryption' and
192192
# 'hw_ephemeral_encryption_format' fields
193193
# Version 1.33: Added 'hw_locked_memory' field
194+
# Version 1.34: Added 'hw_viommu_model' field
194195
# NOTE(efried): When bumping this version, the version of
195196
# ImageMetaPropsPayload must also be bumped. See its docstring for details.
196-
VERSION = '1.33'
197+
VERSION = '1.34'
197198

198199
def obj_make_compatible(self, primitive, target_version):
199200
super(ImageMetaProps, self).obj_make_compatible(primitive,
200201
target_version)
201202
target_version = versionutils.convert_version_to_tuple(target_version)
203+
if target_version < (1, 34):
204+
primitive.pop('hw_viommu_model', None)
202205
if target_version < (1, 33):
203206
primitive.pop('hw_locked_memory', None)
204207
if target_version < (1, 32):
@@ -446,6 +449,9 @@ def obj_make_compatible(self, primitive, target_version):
446449
# name of a NIC device model eg virtio, e1000, rtl8139
447450
'hw_vif_model': fields.VIFModelField(),
448451

452+
# name of IOMMU device model eg virtio, intel, smmuv3, or auto
453+
'hw_viommu_model': fields.VIOMMUModelField(),
454+
449455
# "xen" vs "hvm"
450456
'hw_vm_mode': fields.VMModeField(),
451457

nova/tests/functional/notification_sample_tests/test_instance.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,7 @@ def test_rebuild_server(self):
12311231
'nova_object.data': {},
12321232
'nova_object.name': 'ImageMetaPropsPayload',
12331233
'nova_object.namespace': 'nova',
1234-
'nova_object.version': '1.11',
1234+
'nova_object.version': '1.12',
12351235
},
12361236
'image.size': 58145823,
12371237
'image.tags': [],
@@ -1327,7 +1327,7 @@ def test_rebuild_server_with_trusted_cert(self):
13271327
'nova_object.data': {},
13281328
'nova_object.name': 'ImageMetaPropsPayload',
13291329
'nova_object.namespace': 'nova',
1330-
'nova_object.version': '1.11',
1330+
'nova_object.version': '1.12',
13311331
},
13321332
'image.size': 58145823,
13331333
'image.tags': [],

nova/tests/unit/api/validation/extra_specs/test_validators.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ def test_value__str(self):
7474
('hw:pci_numa_affinity_policy', 'preferred'),
7575
('hw:pci_numa_affinity_policy', 'socket'),
7676
('hw:cpu_policy', 'mixed'),
77+
('hw:viommu_model', 'auto'),
78+
('hw:viommu_model', 'intel'),
79+
('hw:viommu_model', 'smmuv3'),
80+
('hw:viommu_model', 'virtio'),
7781
)
7882
for key, value in valid_specs:
7983
validators.validate(key, value)
@@ -92,6 +96,7 @@ def test_value__str(self):
9296
('hw:pci_numa_affinity_policy', 'requird'),
9397
('hw:pci_numa_affinity_policy', 'prefrred'),
9498
('hw:pci_numa_affinity_policy', 'socet'),
99+
('hw:viommu_model', 'autt'),
95100
)
96101
for key, value in invalid_specs:
97102
with testtools.ExpectedException(exception.ValidationError):

nova/tests/unit/notifications/objects/test_notification.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ def test_payload_is_not_generated_if_notification_format_is_unversioned(
386386
# ImageMetaProps, so when you see a fail here for that reason, you must
387387
# *also* bump the version of ImageMetaPropsPayload. See its docstring for
388388
# more information.
389-
'ImageMetaPropsPayload': '1.11-938809cd33367c52cbc814fb9b6783dc',
389+
'ImageMetaPropsPayload': '1.12-b9c64832d7772c1973e913bacbe0e8f9',
390390
'InstanceActionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
391391
'InstanceActionPayload': '1.8-4fa3da9cbf0761f1f700ae578f36dc2f',
392392
'InstanceActionRebuildNotification':

0 commit comments

Comments
 (0)