[libvirt] [PATCH v3 2/6] libxl: do not enable nested HVM by mere presence of <cpu> element

Marek Marczykowski-Górecki marmarek at invisiblethingslab.com
Sun Dec 10 02:10:47 UTC 2017


<cpu mode='host-passthrough'> element may be used to configure other
features, like NUMA, or CPUID. Do not enable nested HVM (which is in
"preview" state after all) by mere presence of
<cpu mode='host-passthrough'> element, but require explicit <feature
policy='force' name='vmx'/> (or 'svm').
Also, adjust xenconfig driver to appropriately translate to/from
nestedhvm=1.

While at it, adjust xenconfig driver to not override def->cpu if already
set elsewhere. This will help with adding cpuid support.

---
Changes since v2:
 - new patch
---
 src/libxl/libxl_conf.c                         | 10 ++-
 src/xenconfig/xen_xl.c                         | 57 +++++++++----------
 tests/libxlxml2domconfigdata/vnuma-hvm.json    |  1 +-
 tests/xlconfigdata/test-fullvirt-nestedhvm.xml |  4 +-
 4 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index f39e783..1846109 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -355,6 +355,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
 
         if (caps && def->cpu) {
             bool hasHwVirt = false;
+            int nested_hvm = -1;
             bool svm = false, vmx = false;
 
             if (def->cpu->mode != (VIR_CPU_MODE_HOST_PASSTHROUGH)) {
@@ -379,18 +380,23 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
                         case VIR_CPU_FEATURE_FORBID:
                             if ((vmx && STREQ(def->cpu->features[i].name, "vmx")) ||
                                 (svm && STREQ(def->cpu->features[i].name, "svm")))
-                                hasHwVirt = false;
+                                nested_hvm = 0;
                             break;
 
                         case VIR_CPU_FEATURE_FORCE:
                         case VIR_CPU_FEATURE_REQUIRE:
+                            if ((vmx && STREQ(def->cpu->features[i].name, "vmx")) ||
+                                (svm && STREQ(def->cpu->features[i].name, "svm")))
+                                nested_hvm = 1;
+                            break;
                         case VIR_CPU_FEATURE_OPTIONAL:
                         case VIR_CPU_FEATURE_LAST:
                             break;
                     }
                 }
             }
-            libxl_defbool_set(&b_info->u.hvm.nested_hvm, hasHwVirt);
+            if (hasHwVirt && nested_hvm != -1)
+                libxl_defbool_set(&b_info->u.hvm.nested_hvm, nested_hvm);
         }
 
         if (def->nsounds > 0) {
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index 9e239a7..317c7a0 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -170,16 +170,7 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
         if (xenConfigGetBool(conf, "nestedhvm", &val, -1) < 0)
             return -1;
 
-        if (val == 1) {
-            virCPUDefPtr cpu;
-
-            if (VIR_ALLOC(cpu) < 0)
-                return -1;
-
-            cpu->mode = VIR_CPU_MODE_HOST_PASSTHROUGH;
-            cpu->type = VIR_CPU_TYPE_GUEST;
-            def->cpu = cpu;
-        } else if (val == 0) {
+        if (val != -1) {
             const char *vtfeature = NULL;
 
             if (caps && caps->host.cpu && ARCH_IS_X86(def->os.arch)) {
@@ -190,26 +181,29 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
             }
 
             if (vtfeature) {
-                virCPUDefPtr cpu;
-
-                if (VIR_ALLOC(cpu) < 0)
-                    return -1;
+                if (!def->cpu) {
+                    virCPUDefPtr cpu;
+                    if (VIR_ALLOC(cpu) < 0)
+                        return -1;
 
-                if (VIR_ALLOC(cpu->features) < 0) {
-                    VIR_FREE(cpu);
-                    return -1;
+                    cpu->mode = VIR_CPU_MODE_HOST_PASSTHROUGH;
+                    cpu->type = VIR_CPU_TYPE_GUEST;
+                    cpu->nfeatures = 0;
+                    cpu->nfeatures_max = 0;
+                    def->cpu = cpu;
                 }
 
-                if (VIR_STRDUP(cpu->features->name, vtfeature) < 0) {
-                    VIR_FREE(cpu->features);
-                    VIR_FREE(cpu);
-                    return -1;
+                if (val == 0) {
+                    if (virCPUDefAddFeature(def->cpu,
+                                            vtfeature,
+                                            VIR_CPU_FEATURE_DISABLE) < 0)
+                        return -1;
+                } else if (val == 1) {
+                    if (virCPUDefAddFeature(def->cpu,
+                                            vtfeature,
+                                            VIR_CPU_FEATURE_FORCE) < 0)
+                        return -1;
                 }
-                cpu->features->policy = VIR_CPU_FEATURE_DISABLE;
-                cpu->nfeatures = cpu->nfeatures_max = 1;
-                cpu->mode = VIR_CPU_MODE_HOST_PASSTHROUGH;
-                cpu->type = VIR_CPU_TYPE_GUEST;
-                def->cpu = cpu;
             }
         }
     } else {
@@ -1157,6 +1151,7 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
         if (def->cpu &&
             def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
             bool hasHwVirt = true;
+            int nestedhvm = -1;
 
             if (def->cpu->nfeatures) {
                 for (i = 0; i < def->cpu->nfeatures; i++) {
@@ -1166,11 +1161,15 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
                         case VIR_CPU_FEATURE_FORBID:
                             if (STREQ(def->cpu->features[i].name, "vmx") ||
                                 STREQ(def->cpu->features[i].name, "svm"))
-                                hasHwVirt = false;
+                                nestedhvm = 0;
                             break;
 
                         case VIR_CPU_FEATURE_FORCE:
                         case VIR_CPU_FEATURE_REQUIRE:
+                            if (STREQ(def->cpu->features[i].name, "vmx") ||
+                                STREQ(def->cpu->features[i].name, "svm"))
+                                nestedhvm = 1;
+                            break;
                         case VIR_CPU_FEATURE_OPTIONAL:
                         case VIR_CPU_FEATURE_LAST:
                             break;
@@ -1178,7 +1177,9 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
                 }
             }
 
-            if (xenConfigSetInt(conf, "nestedhvm", hasHwVirt) < 0)
+            if (hasHwVirt &&
+                    nestedhvm != -1 &&
+                    xenConfigSetInt(conf, "nestedhvm", nestedhvm) < 0)
                 return -1;
         }
 
diff --git a/tests/libxlxml2domconfigdata/vnuma-hvm.json b/tests/libxlxml2domconfigdata/vnuma-hvm.json
index 3a5071e..2437a84 100644
--- a/tests/libxlxml2domconfigdata/vnuma-hvm.json
+++ b/tests/libxlxml2domconfigdata/vnuma-hvm.json
@@ -113,7 +113,6 @@
             "pae": "True",
             "apic": "True",
             "acpi": "True",
-            "nested_hvm": "True",
             "vga": {
                 "kind": "cirrus"
             },
diff --git a/tests/xlconfigdata/test-fullvirt-nestedhvm.xml b/tests/xlconfigdata/test-fullvirt-nestedhvm.xml
index 8c02e7a..8a55bea 100644
--- a/tests/xlconfigdata/test-fullvirt-nestedhvm.xml
+++ b/tests/xlconfigdata/test-fullvirt-nestedhvm.xml
@@ -14,7 +14,9 @@
     <apic/>
     <pae/>
   </features>
-  <cpu mode='host-passthrough'/>
+  <cpu mode='host-passthrough'>
+    <feature policy='force' name='vmx'/>
+  </cpu>
   <clock offset='variable' adjustment='0' basis='utc'/>
   <on_poweroff>destroy</on_poweroff>
   <on_reboot>restart</on_reboot>
-- 
git-series 0.9.1




More information about the libvir-list mailing list