From 6088fe594a3a5d383e345029473e2dd933dc8220 Mon Sep 17 00:00:00 2001 Message-Id: <6088fe594a3a5d383e345029473e2dd933dc8220@dist-git> From: Pavel Hrdina Date: Wed, 15 May 2019 10:37:46 +0200 Subject: [PATCH] domcapabilities: introduce get_cpu_security_features Get all CPU security features that we should enable for guests. In order to do that we need to get CPU definition from domain capabilities and modify the XML so it is in required format for libvirt CPU baseline APIs. We will prefer the baselineHypervisorCPU API because that considers what QEMU actually supports and we will fallback to baselineCPU API if the better one is not supported by libvirt. This way we can figure out which of the security features are actually available on that specific host for that specific QEMU binary. Signed-off-by: Pavel Hrdina Reviewed-by: Cole Robinson (cherry picked from commit 4a8b6363c0891e37d9532213a046c5c57aedfd8b) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1716402 Signed-off-by: Pavel Hrdina --- virtinst/domcapabilities.py | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/virtinst/domcapabilities.py b/virtinst/domcapabilities.py index 4cbb7f20..28ed8630 100644 --- a/virtinst/domcapabilities.py +++ b/virtinst/domcapabilities.py @@ -8,7 +8,11 @@ import logging import re +import xml.etree.ElementTree as ET +import libvirt + +from .domain import DomainCpu from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty @@ -232,6 +236,59 @@ class DomainCapabilities(XMLBuilder): return [(m.name == "host-model" and m.supported) for m in self.cpu.modes] + def _convert_mode_to_cpu(self, xml): + root = ET.fromstring(xml) + root.tag = "cpu" + root.attrib = None + arch = ET.SubElement(root, "arch") + arch.text = self.arch + return ET.tostring(root, encoding="unicode") + + def _get_expandned_cpu(self, mode): + cpuXML = self._convert_mode_to_cpu(mode.get_xml()) + logging.debug("CPU XML for security flag baseline: %s", cpuXML) + + try: + expandedXML = self.conn.baselineHypervisorCPU( + self.path, self.arch, self.machine, self.domain, [cpuXML], + libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) + except libvirt.libvirtError: + expandedXML = self.conn.baselineCPU([cpuXML], + libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) + + logging.debug("Expanded CPU XML: %s", expandedXML) + + return DomainCpu(self.conn, expandedXML) + + def get_cpu_security_features(self): + sec_features = [ + 'pcid', + 'spec-ctrl', + 'ssbd', + 'pdpe1gb', + 'ibpb', + 'virt-ssbd', + 'amd-ssbd', + 'amd-no-ssb'] + + features = [] + + for m in self.cpu.modes: + if m.name != "host-model" or not m.supported: + continue + + try: + cpu = self._get_expandned_cpu(m) + except libvirt.libvirtError as e: + logging.warning(_("Failed to get expanded CPU XML: %s"), e) + break + + for feature in cpu.features: + if feature.name in sec_features: + features.append(feature.name) + + return features + XML_NAME = "domainCapabilities" os = XMLChildProperty(_OS, is_single=True) -- 2.21.0