vm: improve error message about missing IOMMU

Handle this case specifically, as way too many users ignore the message
during installation and complain it doesn't work later.

Name the problem explicitly, instead of pointing at libvirt error log.

Fixes QubesOS/qubes-issues#4689
This commit is contained in:
Marek Marczykowski-Górecki 2019-10-29 03:13:49 +01:00
parent 89e3ae3945
commit 361550c621
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 23 additions and 0 deletions

View File

@ -314,6 +314,16 @@ class QubesHost:
raise NotImplementedError('This function requires Xen hypervisor') raise NotImplementedError('This function requires Xen hypervisor')
return int(self._physinfo['free_memory']) return int(self._physinfo['free_memory'])
def is_iommu_supported(self):
"""Check if IOMMU is supported on this platform"""
if self._physinfo is None:
try:
self._physinfo = self.app.vmm.xc.physinfo()
except AttributeError:
raise NotImplementedError(
'This function requires Xen hypervisor')
return 'hvm_directio' in self._physinfo['virt_caps']
def get_vm_stats(self, previous_time=None, previous=None, only_vm=None): def get_vm_stats(self, previous_time=None, previous=None, only_vm=None):
"""Measure cpu usage for all domains at once. """Measure cpu usage for all domains at once.

View File

@ -1115,6 +1115,19 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.libvirt_domain.createWithFlags( self.libvirt_domain.createWithFlags(
libvirt.VIR_DOMAIN_START_PAUSED) libvirt.VIR_DOMAIN_START_PAUSED)
except libvirt.libvirtError as exc:
# missing IOMMU?
if self.virt_mode == 'hvm' and \
list(self.devices['pci'].persistent()) and \
not self.app.host.is_iommu_supported():
exc = qubes.exc.QubesException(
'Failed to start an HVM qube with PCI devices assigned '
'- hardware does not support IOMMU/VT-d/AMD-Vi')
self.log.error('Start failed: %s', str(exc))
yield from self.fire_event_async('domain-start-failed',
reason=str(exc))
yield from self.storage.stop()
raise exc
except Exception as exc: except Exception as exc:
self.log.error('Start failed: %s', str(exc)) self.log.error('Start failed: %s', str(exc))
# let anyone receiving domain-pre-start know that startup failed # let anyone receiving domain-pre-start know that startup failed