<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