The reworked API is now called virCPUUpdate and it should change the
provided CPU definition into a one which can be consumed by the QEMU
command line builder:
- host-passthrough remains unchanged
- host-model is turned into custom CPU with a model and features
copied from host
- custom CPU with minimum match is converted similarly to host-model
- optional features are updated according to host's CPU
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
Notes:
Version 2:
- adapted to changes in previous patches
- s/by/by the/ in the commit message
- removed ATTRIBUTE_NONNULL(3)
- s/host->arch/arch/
po/POTFILES.in | 1 +
src/cpu/cpu.c | 61 ++++--
src/cpu/cpu.h | 11 +-
src/cpu/cpu_arm.c | 36 +++-
src/cpu/cpu_ppc64.c | 32 ++--
src/cpu/cpu_x86.c | 212 ++++++++-------------
src/libvirt_private.syms | 2 +-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_process.c | 2 +-
tests/cputest.c | 14 +-
.../cputestdata/x86-host+host-model-nofallback.xml | 2 +-
tests/cputestdata/x86-host+host-model.xml | 2 +-
.../x86-host+host-passthrough-features.xml | 4 +
tests/cputestdata/x86-host+host-passthrough.xml | 19 +-
tests/cputestdata/x86-host+min.xml | 27 +--
tests/cputestdata/x86-host+pentium3.xml | 39 ++--
tests/cputestdata/x86-host-invtsc+host-model.xml | 2 +-
.../cputestdata/x86-host-passthrough-features.xml | 4 +
19 files changed, 228 insertions(+), 246 deletions(-)
create mode 100644 tests/cputestdata/x86-host+host-passthrough-features.xml
create mode 100644 tests/cputestdata/x86-host-passthrough-features.xml
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 25dbc84..1469240 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -43,6 +43,7 @@ src/conf/virchrdev.c
src/conf/virdomainobjlist.c
src/conf/virsecretobj.c
src/cpu/cpu.c
+src/cpu/cpu_arm.c
src/cpu/cpu_map.c
src/cpu/cpu_ppc64.c
src/cpu/cpu_x86.c
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index fae3885..e6f6335 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -579,38 +579,71 @@ cpuBaseline(virCPUDefPtr *cpus,
/**
- * cpuUpdate:
+ * virCPUUpdate:
*
- * @guest: guest CPU definition
+ * @arch: CPU architecture
+ * @guest: guest CPU definition to be updated
* @host: host CPU definition
*
* Updates @guest CPU definition according to @host CPU. This is required to
- * support guest CPU definition which are relative to host CPU, such as CPUs
- * with VIR_CPU_MODE_CUSTOM and optional features or VIR_CPU_MATCH_MINIMUM, or
- * CPUs with non-custom mode (VIR_CPU_MODE_HOST_MODEL,
- * VIR_CPU_MODE_HOST_PASSTHROUGH).
+ * support guest CPU definitions specified relatively to host CPU, such as
+ * CPUs with VIR_CPU_MODE_CUSTOM and optional features or
+ * VIR_CPU_MATCH_MINIMUM, or CPUs with VIR_CPU_MODE_HOST_MODEL.
+ * When the guest CPU was not specified relatively, the function does nothing
+ * and returns success.
*
* Returns 0 on success, -1 on error.
*/
int
-cpuUpdate(virCPUDefPtr guest,
- const virCPUDef *host)
+virCPUUpdate(virArch arch,
+ virCPUDefPtr guest,
+ const virCPUDef *host)
{
struct cpuArchDriver *driver;
- VIR_DEBUG("guest=%p, host=%p", guest, host);
+ VIR_DEBUG("arch=%s, guest=%p mode=%s model=%s, host=%p model=%s",
+ virArchToString(arch), guest, virCPUModeTypeToString(guest->mode),
+ NULLSTR(guest->model), host, NULLSTR(host ? host->model : NULL));
- if ((driver = cpuGetSubDriver(host->arch)) == NULL)
+ if (!(driver = cpuGetSubDriver(arch)))
return -1;
- if (driver->update == NULL) {
+ if (guest->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
+ return 0;
+
+ if (guest->mode == VIR_CPU_MODE_CUSTOM &&
+ guest->match != VIR_CPU_MATCH_MINIMUM) {
+ size_t i;
+ bool optional = false;
+
+ for (i = 0; i < guest->nfeatures; i++) {
+ if (guest->features[i].policy == VIR_CPU_FEATURE_OPTIONAL) {
+ optional = true;
+ break;
+ }
+ }
+
+ if (!optional)
+ return 0;
+ }
+
+ /* We get here if guest CPU is either
+ * - host-model
+ * - custom with minimum match
+ * - custom with optional features
+ */
+ if (!driver->update) {
virReportError(VIR_ERR_NO_SUPPORT,
- _("cannot update guest CPU data for %s architecture"),
- virArchToString(host->arch));
+ _("cannot update guest CPU for %s architecture"),
+ virArchToString(arch));
return -1;
}
- return driver->update(guest, host);
+ if (driver->update(guest, host) < 0)
+ return -1;
+
+ VIR_DEBUG("model=%s", NULLSTR(guest->model));
+ return 0;
}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 422818e..dac7688 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -87,8 +87,8 @@ typedef virCPUDefPtr
unsigned int flags);
typedef int
-(*cpuArchUpdate) (virCPUDefPtr guest,
- const virCPUDef *host);
+(*virCPUArchUpdate)(virCPUDefPtr guest,
+ const virCPUDef *host);
typedef int
(*cpuArchHasFeature) (const virCPUData *data,
@@ -114,7 +114,7 @@ struct cpuArchDriver {
cpuArchNodeData nodeData;
cpuArchGuestData guestData;
cpuArchBaseline baseline;
- cpuArchUpdate update;
+ virCPUArchUpdate update;
cpuArchHasFeature hasFeature;
cpuArchDataFormat dataFormat;
cpuArchDataParse dataParse;
@@ -182,9 +182,10 @@ cpuBaseline (virCPUDefPtr *cpus,
ATTRIBUTE_NONNULL(1);
int
-cpuUpdate (virCPUDefPtr guest,
+virCPUUpdate(virArch arch,
+ virCPUDefPtr guest,
const virCPUDef *host)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ ATTRIBUTE_NONNULL(2);
int
cpuHasFeature(const virCPUData *data,
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index a3aed6b..e8ab954 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -43,15 +43,41 @@ armDataFree(virCPUDataPtr data)
VIR_FREE(data);
}
+
static int
-armUpdate(virCPUDefPtr guest,
- const virCPUDef *host)
+virCPUarmUpdate(virCPUDefPtr guest,
+ const virCPUDef *host)
{
+ int ret = -1;
+ virCPUDefPtr updated = NULL;
+
+ if (guest->mode != VIR_CPU_MODE_HOST_MODEL)
+ return 0;
+
+ if (!host) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unknown host CPU model"));
+ goto cleanup;
+ }
+
+ if (!(updated = virCPUDefCopyWithoutModel(guest)))
+ goto cleanup;
+
+ updated->mode = VIR_CPU_MODE_CUSTOM;
+ if (virCPUDefCopyModel(updated, host, true) < 0)
+ goto cleanup;
+
+ virCPUDefStealModel(guest, updated);
+ guest->mode = VIR_CPU_MODE_CUSTOM;
guest->match = VIR_CPU_MATCH_EXACT;
- virCPUDefFreeModel(guest);
- return virCPUDefCopyModel(guest, host, true);
+ ret = 0;
+
+ cleanup:
+ virCPUDefFree(updated);
+ return ret;
}
+
static virCPUCompareResult
armGuestData(virCPUDefPtr host ATTRIBUTE_UNUSED,
virCPUDefPtr guest ATTRIBUTE_UNUSED,
@@ -104,6 +130,6 @@ struct cpuArchDriver cpuDriverArm = {
.nodeData = NULL,
.guestData = armGuestData,
.baseline = armBaseline,
- .update = armUpdate,
+ .update = virCPUarmUpdate,
.hasFeature = NULL,
};
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index ad2d6a7..00faa22 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -751,27 +751,21 @@ ppc64DriverGuestData(virCPUDefPtr host,
}
static int
-ppc64DriverUpdate(virCPUDefPtr guest,
- const virCPUDef *host)
+virCPUppc64Update(virCPUDefPtr guest,
+ const virCPUDef *host ATTRIBUTE_UNUSED)
{
- switch ((virCPUMode) guest->mode) {
- case VIR_CPU_MODE_HOST_PASSTHROUGH:
+ /*
+ * - host-passthrough doesn't even get here
+ * - host-model is used for host CPU running in a compatibility mode and
+ * it needs to remain unchanged
+ * - custom doesn't support any optional features, there's nothing to
+ * update
+ */
+
+ if (guest->mode == VIR_CPU_MODE_CUSTOM)
guest->match = VIR_CPU_MATCH_EXACT;
- guest->fallback = VIR_CPU_FALLBACK_FORBID;
- virCPUDefFreeModel(guest);
- return virCPUDefCopyModel(guest, host, true);
- case VIR_CPU_MODE_HOST_MODEL:
- case VIR_CPU_MODE_CUSTOM:
- return 0;
-
- case VIR_CPU_MODE_LAST:
- break;
- }
-
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Unexpected CPU mode: %d"), guest->mode);
- return -1;
+ return 0;
}
static virCPUDefPtr
@@ -915,7 +909,7 @@ struct cpuArchDriver cpuDriverPPC64 = {
.nodeData = ppc64DriverNodeData,
.guestData = ppc64DriverGuestData,
.baseline = ppc64DriverBaseline,
- .update = ppc64DriverUpdate,
+ .update = virCPUppc64Update,
.hasFeature = NULL,
.getModels = ppc64DriverGetModels,
};
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 8c95b7a..bd26703 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1122,40 +1122,6 @@ x86ModelFromCPU(const virCPUDef *cpu,
}
-static int
-x86ModelSubtractCPU(virCPUx86ModelPtr model,
- const virCPUDef *cpu,
- virCPUx86MapPtr map)
-{
- virCPUx86ModelPtr cpu_model;
- size_t i;
-
- if (!(cpu_model = x86ModelFind(map, cpu->model))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Unknown CPU model %s"),
- cpu->model);
- return -1;
- }
-
- x86DataSubtract(&model->data, &cpu_model->data);
-
- for (i = 0; i < cpu->nfeatures; i++) {
- virCPUx86FeaturePtr feature;
-
- if (!(feature = x86FeatureFind(map, cpu->features[i].name))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Unknown CPU feature %s"),
- cpu->features[i].name);
- return -1;
- }
-
- x86DataSubtract(&model->data, &feature->data);
- }
-
- return 0;
-}
-
-
static virCPUx86CompareResult
x86ModelCompare(virCPUx86ModelPtr model1,
virCPUx86ModelPtr model2)
@@ -2533,23 +2499,85 @@ x86Baseline(virCPUDefPtr *cpus,
static int
-x86UpdateCustom(virCPUDefPtr guest,
+x86UpdateHostModel(virCPUDefPtr guest,
+ const virCPUDef *host,
+ virCPUx86MapPtr map)
+{
+ virCPUDefPtr updated = NULL;
+ size_t i;
+ int ret = -1;
+
+ if (!(updated = virCPUDefCopyWithoutModel(host)))
+ goto cleanup;
+
+ /* Remove non-migratable features by default */
+ updated->type = VIR_CPU_TYPE_GUEST;
+ updated->mode = VIR_CPU_MODE_CUSTOM;
+ if (virCPUDefCopyModel(updated, host, true) < 0)
+ goto cleanup;
+
+ i = 0;
+ while (i < updated->nfeatures) {
+ if (x86FeatureIsMigratable(updated->features[i].name, map) &&
+ STRNEQ(updated->features[i].name, "cmt") &&
+ STRNEQ(updated->features[i].name, "mbm_total") &&
+ STRNEQ(updated->features[i].name, "mbm_local")) {
+ i++;
+ } else {
+ VIR_FREE(updated->features[i].name);
+ VIR_DELETE_ELEMENT_INPLACE(updated->features, i, updated->nfeatures);
+ }
+ }
+
+ if (guest->vendor_id) {
+ VIR_FREE(updated->vendor_id);
+ if (VIR_STRDUP(updated->vendor_id, guest->vendor_id) < 0)
+ goto cleanup;
+ }
+
+ for (i = 0; i < guest->nfeatures; i++) {
+ if (virCPUDefUpdateFeature(updated,
+ guest->features[i].name,
+ guest->features[i].policy) < 0)
+ goto cleanup;
+ }
+
+ virCPUDefStealModel(guest, updated);
+ guest->mode = VIR_CPU_MODE_CUSTOM;
+ guest->match = VIR_CPU_MATCH_EXACT;
+ ret = 0;
+
+ cleanup:
+ virCPUDefFree(updated);
+ return ret;
+}
+
+
+static int
+virCPUx86Update(virCPUDefPtr guest,
const virCPUDef *host)
{
+ virCPUx86ModelPtr model = NULL;
+ virCPUx86MapPtr map;
int ret = -1;
size_t i;
- virCPUx86MapPtr map;
- virCPUx86ModelPtr host_model = NULL;
- if (!(map = virCPUx86GetMap()) ||
- !(host_model = x86ModelFromCPU(host, map, VIR_CPU_FEATURE_REQUIRE)))
+ if (!host) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unknown host CPU model"));
+ return -1;
+ }
+
+ if (!(map = virCPUx86GetMap()))
+ return -1;
+
+ if (!(model = x86ModelFromCPU(host, map, -1)))
goto cleanup;
for (i = 0; i < guest->nfeatures; i++) {
if (guest->features[i].policy == VIR_CPU_FEATURE_OPTIONAL) {
int supported = x86FeatureInData(guest->features[i].name,
- &host_model->data, map);
-
+ &model->data, map);
if (supported < 0)
goto cleanup;
else if (supported)
@@ -2559,107 +2587,19 @@ x86UpdateCustom(virCPUDefPtr guest,
}
}
- if (guest->match == VIR_CPU_MATCH_MINIMUM) {
- guest->match = VIR_CPU_MATCH_EXACT;
- if (x86ModelSubtractCPU(host_model, guest, map) ||
- x86DataToCPUFeatures(guest, VIR_CPU_FEATURE_REQUIRE,
- &host_model->data, map))
- goto cleanup;
- }
-
- ret = 0;
+ if (guest->mode == VIR_CPU_MODE_HOST_MODEL ||
+ guest->match == VIR_CPU_MATCH_MINIMUM)
+ ret = x86UpdateHostModel(guest, host, map);
+ else
+ ret = 0;
cleanup:
- x86ModelFree(host_model);
+ x86ModelFree(model);
return ret;
}
static int
-x86UpdateHostModel(virCPUDefPtr guest,
- const virCPUDef *host,
- bool passthrough)
-{
- virCPUDefPtr oldguest = NULL;
- virCPUx86MapPtr map;
- size_t i;
- int ret = -1;
-
- if (!(map = virCPUx86GetMap()))
- goto cleanup;
-
- /* update the host model according to the desired configuration */
- if (!(oldguest = virCPUDefCopy(guest)))
- goto cleanup;
-
- virCPUDefFreeModel(guest);
- if (virCPUDefCopyModel(guest, host, true) < 0)
- goto cleanup;
-
- if (oldguest->vendor_id) {
- VIR_FREE(guest->vendor_id);
- if (VIR_STRDUP(guest->vendor_id, oldguest->vendor_id) < 0)
- goto cleanup;
- }
-
- /* Remove non-migratable features and CMT related features which QEMU
- * knows nothing about.
- * Note: this only works as long as no CPU model contains non-migratable
- * features directly */
- i = 0;
- while (i < guest->nfeatures) {
- if (x86FeatureIsMigratable(guest->features[i].name, map) &&
- STRNEQ(guest->features[i].name, "cmt") &&
- STRNEQ(guest->features[i].name, "mbm_total") &&
- STRNEQ(guest->features[i].name, "mbm_local")) {
- i++;
- } else {
- VIR_FREE(guest->features[i].name);
- VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures);
- }
- }
- for (i = 0; !passthrough && i < oldguest->nfeatures; i++) {
- if (virCPUDefUpdateFeature(guest,
- oldguest->features[i].name,
- oldguest->features[i].policy) < 0)
- goto cleanup;
- }
-
- ret = 0;
-
- cleanup:
- virCPUDefFree(oldguest);
- return ret;
-}
-
-
-static int
-x86Update(virCPUDefPtr guest,
- const virCPUDef *host)
-{
- switch ((virCPUMode) guest->mode) {
- case VIR_CPU_MODE_CUSTOM:
- return x86UpdateCustom(guest, host);
-
- case VIR_CPU_MODE_HOST_MODEL:
- guest->match = VIR_CPU_MATCH_EXACT;
- return x86UpdateHostModel(guest, host, false);
-
- case VIR_CPU_MODE_HOST_PASSTHROUGH:
- guest->match = VIR_CPU_MATCH_MINIMUM;
- return x86UpdateHostModel(guest, host, true);
-
- case VIR_CPU_MODE_LAST:
- break;
- }
-
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Unexpected CPU mode: %d"), guest->mode);
- return -1;
-}
-
-
-static int
x86HasFeature(const virCPUData *data,
const char *name)
{
@@ -2716,7 +2656,7 @@ struct cpuArchDriver cpuDriverX86 = {
#endif
.guestData = x86GuestData,
.baseline = x86Baseline,
- .update = x86Update,
+ .update = virCPUx86Update,
.hasFeature = x86HasFeature,
.dataFormat = x86CPUDataFormat,
.dataParse = x86CPUDataParse,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3f5df71..5e9a81f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -975,7 +975,7 @@ cpuGetModels;
cpuGuestData;
cpuHasFeature;
cpuNodeData;
-cpuUpdate;
+virCPUUpdate;
# cpu/cpu_x86.h
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d6462d3..b96f101 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6588,7 +6588,7 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
if (cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
!migrating &&
- cpuUpdate(cpu, host) < 0)
+ virCPUUpdate(def->os.arch, cpu, host) < 0)
goto cleanup;
if (compareAgainstHost &&
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 0e30381..3c46a06 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3407,7 +3407,7 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
goto cleanup;
}
- if (cpuUpdate(def->cpu, caps->host.cpu) < 0)
+ if (virCPUUpdate(def->os.arch, def->cpu, caps->host.cpu) < 0)
goto cleanup;
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 83e64b2..d76d0c0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4487,7 +4487,7 @@ qemuProcessStartValidateGuestCPU(virDomainObjPtr vm,
if (cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
flags & VIR_QEMU_PROCESS_START_NEW &&
- cpuUpdate(cpu, host) < 0)
+ virCPUUpdate(vm->def->os.arch, cpu, host) < 0)
goto cleanup;
cmp = cpuGuestData(host, cpu, &data, &compare_msg);
diff --git a/tests/cputest.c b/tests/cputest.c
index ee779fb..e6696e9 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -398,7 +398,7 @@ cpuTestUpdate(const void *arg)
!(cpu = cpuTestLoadXML(data->arch, data->name)))
goto cleanup;
- if (cpuUpdate(cpu, host) < 0)
+ if (virCPUUpdate(host->arch, cpu, host) < 0)
goto cleanup;
if (virAsprintf(&result, "%s+%s", data->host, data->name) <
0)
@@ -622,11 +622,14 @@ mymain(void)
host "/" cpu " (" #result ")",
\
host, cpu, NULL, 0, NULL, 0, result)
+#define DO_TEST_UPDATE_ONLY(arch, host, cpu) \
+ DO_TEST(arch, cpuTestUpdate, \
+ cpu " on " host, \
+ host, cpu, NULL, 0, NULL, 0, 0) \
+
#define DO_TEST_UPDATE(arch, host, cpu, result) \
do { \
- DO_TEST(arch, cpuTestUpdate, \
- cpu " on " host, \
- host, cpu, NULL, 0, NULL, 0, 0); \
+ DO_TEST_UPDATE_ONLY(arch, host, cpu); \
DO_TEST_COMPARE(arch, host, host "+" cpu, result); \
} while (0)
@@ -737,8 +740,9 @@ mymain(void)
DO_TEST_UPDATE("x86", "host", "guest",
VIR_CPU_COMPARE_SUPERSET);
DO_TEST_UPDATE("x86", "host", "host-model",
VIR_CPU_COMPARE_IDENTICAL);
DO_TEST_UPDATE("x86", "host", "host-model-nofallback",
VIR_CPU_COMPARE_IDENTICAL);
- DO_TEST_UPDATE("x86", "host", "host-passthrough",
VIR_CPU_COMPARE_IDENTICAL);
DO_TEST_UPDATE("x86", "host-invtsc", "host-model",
VIR_CPU_COMPARE_SUPERSET);
+ DO_TEST_UPDATE_ONLY("x86", "host",
"host-passthrough");
+ DO_TEST_UPDATE_ONLY("x86", "host",
"host-passthrough-features");
DO_TEST_UPDATE("ppc64", "host", "guest",
VIR_CPU_COMPARE_IDENTICAL);
DO_TEST_UPDATE("ppc64", "host", "guest-nofallback",
VIR_CPU_COMPARE_INCOMPATIBLE);
diff --git a/tests/cputestdata/x86-host+host-model-nofallback.xml
b/tests/cputestdata/x86-host+host-model-nofallback.xml
index bbb68fb..0c3ede0 100644
--- a/tests/cputestdata/x86-host+host-model-nofallback.xml
+++ b/tests/cputestdata/x86-host+host-model-nofallback.xml
@@ -1,4 +1,4 @@
-<cpu mode='host-model' match='exact'>
+<cpu mode='custom' match='exact'>
<model fallback='forbid'>Penryn</model>
<vendor>Intel</vendor>
<topology sockets='1' cores='2' threads='1'/>
diff --git a/tests/cputestdata/x86-host+host-model.xml
b/tests/cputestdata/x86-host+host-model.xml
index c1014e2..a284767 100644
--- a/tests/cputestdata/x86-host+host-model.xml
+++ b/tests/cputestdata/x86-host+host-model.xml
@@ -1,4 +1,4 @@
-<cpu mode='host-model' match='exact'>
+<cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model>
<vendor>Intel</vendor>
<feature policy='require' name='dca'/>
diff --git a/tests/cputestdata/x86-host+host-passthrough-features.xml
b/tests/cputestdata/x86-host+host-passthrough-features.xml
new file mode 100644
index 0000000..dc2b775
--- /dev/null
+++ b/tests/cputestdata/x86-host+host-passthrough-features.xml
@@ -0,0 +1,4 @@
+<cpu mode='host-passthrough'>
+ <feature policy='disable' name='dca'/>
+ <feature policy='force' name='vmx'/>
+</cpu>
diff --git a/tests/cputestdata/x86-host+host-passthrough.xml
b/tests/cputestdata/x86-host+host-passthrough.xml
index 721fae5..655c7a7 100644
--- a/tests/cputestdata/x86-host+host-passthrough.xml
+++ b/tests/cputestdata/x86-host+host-passthrough.xml
@@ -1,18 +1 @@
-<cpu mode='host-passthrough' match='minimum'>
- <model>Penryn</model>
- <vendor>Intel</vendor>
- <feature policy='require' name='dca'/>
- <feature policy='require' name='xtpr'/>
- <feature policy='require' name='tm2'/>
- <feature policy='require' name='est'/>
- <feature policy='require' name='vmx'/>
- <feature policy='require' name='ds_cpl'/>
- <feature policy='require' name='monitor'/>
- <feature policy='require' name='pbe'/>
- <feature policy='require' name='tm'/>
- <feature policy='require' name='ht'/>
- <feature policy='require' name='ss'/>
- <feature policy='require' name='acpi'/>
- <feature policy='require' name='ds'/>
- <feature policy='require' name='vme'/>
-</cpu>
+<cpu mode='host-passthrough'/>
diff --git a/tests/cputestdata/x86-host+min.xml b/tests/cputestdata/x86-host+min.xml
index 6d2d5cd..a284767 100644
--- a/tests/cputestdata/x86-host+min.xml
+++ b/tests/cputestdata/x86-host+min.xml
@@ -1,17 +1,18 @@
<cpu mode='custom' match='exact'>
<model fallback='allow'>Penryn</model>
- <feature policy='require' name='vme'/>
- <feature policy='require' name='ds'/>
- <feature policy='require' name='acpi'/>
- <feature policy='require' name='ss'/>
- <feature policy='require' name='ht'/>
- <feature policy='require' name='tm'/>
- <feature policy='require' name='pbe'/>
- <feature policy='require' name='monitor'/>
- <feature policy='require' name='ds_cpl'/>
- <feature policy='require' name='vmx'/>
- <feature policy='require' name='est'/>
- <feature policy='require' name='tm2'/>
- <feature policy='require' name='xtpr'/>
+ <vendor>Intel</vendor>
<feature policy='require' name='dca'/>
+ <feature policy='require' name='xtpr'/>
+ <feature policy='require' name='tm2'/>
+ <feature policy='require' name='est'/>
+ <feature policy='require' name='vmx'/>
+ <feature policy='require' name='ds_cpl'/>
+ <feature policy='require' name='monitor'/>
+ <feature policy='require' name='pbe'/>
+ <feature policy='require' name='tm'/>
+ <feature policy='require' name='ht'/>
+ <feature policy='require' name='ss'/>
+ <feature policy='require' name='acpi'/>
+ <feature policy='require' name='ds'/>
+ <feature policy='require' name='vme'/>
</cpu>
diff --git a/tests/cputestdata/x86-host+pentium3.xml
b/tests/cputestdata/x86-host+pentium3.xml
index a8c15f4..a284767 100644
--- a/tests/cputestdata/x86-host+pentium3.xml
+++ b/tests/cputestdata/x86-host+pentium3.xml
@@ -1,27 +1,18 @@
<cpu mode='custom' match='exact'>
- <model fallback='allow'>pentium3</model>
- <feature policy='require' name='apic'/>
- <feature policy='require' name='clflush'/>
- <feature policy='require' name='ds'/>
- <feature policy='require' name='acpi'/>
- <feature policy='require' name='sse2'/>
- <feature policy='require' name='ss'/>
- <feature policy='require' name='ht'/>
- <feature policy='require' name='tm'/>
- <feature policy='require' name='pbe'/>
- <feature policy='require' name='pni'/>
- <feature policy='require' name='monitor'/>
- <feature policy='require' name='ds_cpl'/>
- <feature policy='require' name='vmx'/>
- <feature policy='require' name='est'/>
- <feature policy='require' name='tm2'/>
- <feature policy='require' name='ssse3'/>
- <feature policy='require' name='cx16'/>
- <feature policy='require' name='xtpr'/>
+ <model fallback='allow'>Penryn</model>
+ <vendor>Intel</vendor>
<feature policy='require' name='dca'/>
- <feature policy='require' name='sse4.1'/>
- <feature policy='require' name='syscall'/>
- <feature policy='require' name='nx'/>
- <feature policy='require' name='lm'/>
- <feature policy='require' name='lahf_lm'/>
+ <feature policy='require' name='xtpr'/>
+ <feature policy='require' name='tm2'/>
+ <feature policy='require' name='est'/>
+ <feature policy='require' name='vmx'/>
+ <feature policy='require' name='ds_cpl'/>
+ <feature policy='require' name='monitor'/>
+ <feature policy='require' name='pbe'/>
+ <feature policy='require' name='tm'/>
+ <feature policy='require' name='ht'/>
+ <feature policy='require' name='ss'/>
+ <feature policy='require' name='acpi'/>
+ <feature policy='require' name='ds'/>
+ <feature policy='require' name='vme'/>
</cpu>
diff --git a/tests/cputestdata/x86-host-invtsc+host-model.xml
b/tests/cputestdata/x86-host-invtsc+host-model.xml
index ad1bbf8..998ed23 100644
--- a/tests/cputestdata/x86-host-invtsc+host-model.xml
+++ b/tests/cputestdata/x86-host-invtsc+host-model.xml
@@ -1,4 +1,4 @@
-<cpu mode='host-model' match='exact'>
+<cpu mode='custom' match='exact'>
<model fallback='allow'>SandyBridge</model>
<vendor>Intel</vendor>
<feature policy='require' name='osxsave'/>
diff --git a/tests/cputestdata/x86-host-passthrough-features.xml
b/tests/cputestdata/x86-host-passthrough-features.xml
new file mode 100644
index 0000000..dc2b775
--- /dev/null
+++ b/tests/cputestdata/x86-host-passthrough-features.xml
@@ -0,0 +1,4 @@
+<cpu mode='host-passthrough'>
+ <feature policy='disable' name='dca'/>
+ <feature policy='force' name='vmx'/>
+</cpu>
--
2.10.0