This adds support for host-model and host-passthrough CPU modes to qemu
driver. The host-passthrough mode is mapped to -cpu host.
---
Notes:
Version 2:
- more verbose commit messages
- portability fixes in shell scripts
src/libvirt_private.syms | 1 +
src/qemu/qemu_capabilities.c | 6 +-
src/qemu/qemu_capabilities.h | 9 +-
src/qemu/qemu_command.c | 97 +++++++++++++-------
tests/qemuhelptest.c | 21 +++--
tests/qemuxml2argvdata/qemu-lib.sh | 50 ++++++++++
tests/qemuxml2argvdata/qemu-supported-cpus.sh | 15 +++
tests/qemuxml2argvdata/qemu.sh | 51 +----------
.../qemuxml2argv-cpu-host-model-fallback.args | 19 ++++
.../qemuxml2argv-cpu-host-model-fallback.xml | 19 ++++
.../qemuxml2argv-cpu-host-model-nofallback.xml | 21 ++++
.../qemuxml2argv-cpu-host-model.args | 19 ++++
.../qemuxml2argv-cpu-host-model.xml | 19 ++++
.../qemuxml2argv-cpu-host-passthrough.args | 19 ++++
.../qemuxml2argv-cpu-host-passthrough.xml | 19 ++++
.../qemuxml2argv-cpu-qemu-host-passthrough.xml | 19 ++++
tests/qemuxml2argvtest.c | 7 ++
17 files changed, 314 insertions(+), 97 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemu-lib.sh
create mode 100755 tests/qemuxml2argvdata/qemu-supported-cpus.sh
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-nofallback.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-qemu-host-passthrough.xml
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ac2a892..a64e9ae 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -187,6 +187,7 @@ virCPUDefFormatBuf;
virCPUDefFree;
virCPUDefFreeModel;
virCPUDefParseXML;
+virCPUModeTypeToString;
# datatypes.h
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6842cfe..61cdfb9 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -145,8 +145,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"no-acpi",
"fsdev-readonly",
- "virtio-blk-pci.scsi",
+ "virtio-blk-pci.scsi", /* 80 */
"blk-sg-io",
+ "cpu-host",
);
struct qemu_feature_flags {
@@ -1181,6 +1182,9 @@ qemuCapsComputeCmdFlags(const char *help,
*/
if (version >= 12000)
qemuCapsSet(flags, QEMU_CAPS_PCI_ROMBAR);
+
+ if (version >= 11000)
+ qemuCapsSet(flags, QEMU_CAPS_CPU_HOST);
}
/* We parse the output of 'qemu -help' to get the QEMU
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d47177c..17ef99c 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -113,13 +113,14 @@ enum qemuCapsFlags {
QEMU_CAPS_NO_SHUTDOWN = 74, /* usable -no-shutdown */
QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */
- QEMU_CAPS_PCI_ROMBAR = 76, /* -device rombar=0|1 */
+ QEMU_CAPS_PCI_ROMBAR = 76, /* -device rombar=0|1 */
QEMU_CAPS_ICH9_AHCI = 77, /* -device ich9-ahci */
QEMU_CAPS_NO_ACPI = 78, /* -no-acpi */
- QEMU_CAPS_FSDEV_READONLY =79, /* -fsdev readonly supported */
+ QEMU_CAPS_FSDEV_READONLY = 79, /* -fsdev readonly supported */
- QEMU_CAPS_VIRTIO_BLK_SCSI = 80, /* virtio-blk-pci.scsi */
- QEMU_CAPS_VIRTIO_BLK_SG_IO = 81, /* support for SG_IO commands, reportedly added in
0.11 */
+ QEMU_CAPS_VIRTIO_BLK_SCSI = 80, /* virtio-blk-pci.scsi */
+ QEMU_CAPS_VIRTIO_BLK_SG_IO = 81, /* support for SG_IO commands, reportedly added in
0.11 */
+ QEMU_CAPS_CPU_HOST = 82, /* support for -cpu host */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4d7842e..b11a48e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3428,10 +3428,12 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
virBitmapPtr qemuCaps,
const struct utsname *ut,
char **opt,
- bool *hasHwVirt)
+ bool *hasHwVirt,
+ bool migrating)
{
const virCPUDefPtr host = driver->caps->host.cpu;
virCPUDefPtr guest = NULL;
+ virCPUDefPtr cpu = NULL;
unsigned int ncpus = 0;
const char **cpus = NULL;
union cpuData *data = NULL;
@@ -3441,7 +3443,21 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
*hasHwVirt = false;
- if (def->cpu && def->cpu->model) {
+ if (def->cpu &&
+ (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
+ if (!(cpu = virCPUDefCopy(def->cpu)))
+ goto cleanup;
+ if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
+ !migrating &&
+ cpuUpdate(cpu, host) < 0)
+ goto cleanup;
+ }
+
+ if (cpu) {
+ virCPUCompareResult cmp;
+ const char *preferred;
+ int hasSVM;
+
if (host &&
qemuCapsProbeCPUModels(emulator, qemuCaps, host->arch,
&ncpus, &cpus) < 0)
@@ -3452,18 +3468,12 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
_("CPU specification not supported by
hypervisor"));
goto cleanup;
}
- }
- if (ncpus > 0 && host) {
- virCPUCompareResult cmp;
- const char *preferred;
- int hasSVM;
-
- cmp = cpuGuestData(host, def->cpu, &data);
+ cmp = cpuGuestData(host, cpu, &data);
switch (cmp) {
case VIR_CPU_COMPARE_INCOMPATIBLE:
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("guest CPU is not compatible with host
CPU"));
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest CPU is not compatible with host CPU"));
/* fall through */
case VIR_CPU_COMPARE_ERROR:
goto cleanup;
@@ -3472,39 +3482,55 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
break;
}
- if (VIR_ALLOC(guest) < 0 || !(guest->arch = strdup(host->arch)))
- goto no_memory;
-
- if (def->cpu->match == VIR_CPU_MATCH_MINIMUM)
- preferred = host->model;
- else
- preferred = def->cpu->model;
-
- guest->type = VIR_CPU_TYPE_GUEST;
- guest->fallback = def->cpu->fallback;
- if (cpuDecode(guest, data, cpus, ncpus, preferred) < 0)
- goto cleanup;
-
/* Only 'svm' requires --enable-nesting. The nested
* 'vmx' patches now simply hook off the CPU features
*/
- hasSVM = cpuHasFeature(guest->arch, data, "svm");
+ hasSVM = cpuHasFeature(host->arch, data, "svm");
if (hasSVM < 0)
goto cleanup;
*hasHwVirt = hasSVM > 0 ? true : false;
- virBufferAdd(&buf, guest->model, -1);
- for (i = 0; i < guest->nfeatures; i++) {
- char sign;
- if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
- sign = '-';
+ if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
+ const char *mode = virCPUModeTypeToString(cpu->mode);
+ if (!qemuCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU mode '%s' is not supported by
QEMU"
+ " binary"), mode);
+ goto cleanup;
+ }
+ if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU mode '%s' is only supported with
kvm"),
+ mode);
+ goto cleanup;
+ }
+ virBufferAddLit(&buf, "host");
+ } else {
+ if (VIR_ALLOC(guest) < 0 || !(guest->arch = strdup(host->arch)))
+ goto no_memory;
+
+ if (cpu->match == VIR_CPU_MATCH_MINIMUM)
+ preferred = host->model;
else
- sign = '+';
+ preferred = cpu->model;
- virBufferAsprintf(&buf, ",%c%s", sign,
guest->features[i].name);
+ guest->type = VIR_CPU_TYPE_GUEST;
+ guest->fallback = cpu->fallback;
+ if (cpuDecode(guest, data, cpus, ncpus, preferred) < 0)
+ goto cleanup;
+
+ virBufferAdd(&buf, guest->model, -1);
+ for (i = 0; i < guest->nfeatures; i++) {
+ char sign;
+ if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
+ sign = '-';
+ else
+ sign = '+';
+
+ virBufferAsprintf(&buf, ",%c%s", sign,
guest->features[i].name);
+ }
}
- }
- else {
+ } else {
/*
* Need to force a 32-bit guest CPU type if
*
@@ -3535,6 +3561,7 @@ cleanup:
if (guest)
cpuDataFree(guest->arch, data);
virCPUDefFree(guest);
+ virCPUDefFree(cpu);
if (cpus) {
for (i = 0; i < ncpus; i++)
@@ -3757,7 +3784,7 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArgList(cmd, "-M", def->os.machine, NULL);
if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps,
- &ut, &cpu, &hasHwVirt) < 0)
+ &ut, &cpu, &hasHwVirt, !!migrateFrom) < 0)
goto error;
if (cpu) {
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 1ef0d9b..87d3729 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -330,7 +330,8 @@ mymain(void)
QEMU_CAPS_NO_SHUTDOWN,
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_NO_ACPI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
DO_TEST("qemu-kvm-0.12.1.2-rhel60", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -378,7 +379,8 @@ mymain(void)
QEMU_CAPS_NO_SHUTDOWN,
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_NO_ACPI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
DO_TEST("qemu-kvm-0.12.3", 12003, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -419,7 +421,8 @@ mymain(void)
QEMU_CAPS_NO_SHUTDOWN,
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_NO_ACPI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
DO_TEST("qemu-kvm-0.13.0", 13000, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -476,7 +479,8 @@ mymain(void)
QEMU_CAPS_NO_SHUTDOWN,
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_NO_ACPI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
DO_TEST("qemu-kvm-0.12.1.2-rhel61", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -530,7 +534,8 @@ mymain(void)
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_NO_ACPI,
QEMU_CAPS_VIRTIO_BLK_SCSI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
DO_TEST("qemu-kvm-0.12.1.2-rhel62-beta", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -592,7 +597,8 @@ mymain(void)
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_NO_ACPI,
QEMU_CAPS_VIRTIO_BLK_SCSI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
DO_TEST("qemu-1.0", 1000000, 0, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -658,7 +664,8 @@ mymain(void)
QEMU_CAPS_NO_ACPI,
QEMU_CAPS_FSDEV_READONLY,
QEMU_CAPS_VIRTIO_BLK_SCSI,
- QEMU_CAPS_VIRTIO_BLK_SG_IO);
+ QEMU_CAPS_VIRTIO_BLK_SG_IO,
+ QEMU_CAPS_CPU_HOST);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/tests/qemuxml2argvdata/qemu-lib.sh b/tests/qemuxml2argvdata/qemu-lib.sh
new file mode 100644
index 0000000..ba19119
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemu-lib.sh
@@ -0,0 +1,50 @@
+candidates="/usr/bin/qemu-kvm
+ /usr/libexec/qemu-kvm
+ /usr/bin/qemu-system-x86_64
+ /usr/bin/qemu"
+qemu=
+for candidate in $candidates; do
+ if test -x $candidate; then
+ qemu=$candidate
+ break
+ fi
+done
+
+real_qemu()
+{
+ if test x$qemu != x; then
+ exec $qemu "$@"
+ else
+ return 1
+ fi
+}
+
+faked_machine()
+{
+ echo "pc"
+}
+
+faked_cpu()
+{
+ cat <<EOF
+x86 Opteron_G3
+x86 Opteron_G2
+x86 Opteron_G1
+x86 Nehalem
+x86 Penryn
+x86 Conroe
+x86 [n270]
+x86 [athlon]
+x86 [pentium3]
+x86 [pentium2]
+x86 [pentium]
+x86 [486]
+x86 [coreduo]
+x86 [qemu32]
+x86 [kvm64]
+x86 [core2duo]
+x86 [phenom]
+x86 [qemu64]
+x86 [host]
+EOF
+}
diff --git a/tests/qemuxml2argvdata/qemu-supported-cpus.sh
b/tests/qemuxml2argvdata/qemu-supported-cpus.sh
new file mode 100755
index 0000000..ed3ae94
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemu-supported-cpus.sh
@@ -0,0 +1,15 @@
+#! /bin/sh
+
+. $(dirname $0)/qemu-lib.sh
+
+case $* in
+"-M ?")
+ faked_machine
+ ;;
+"-cpu ?")
+ faked_cpu | grep -Fv '['
+ ;;
+*)
+ real_qemu "$@"
+ ;;
+esac
diff --git a/tests/qemuxml2argvdata/qemu.sh b/tests/qemuxml2argvdata/qemu.sh
index 6d5d354..38da0b3 100755
--- a/tests/qemuxml2argvdata/qemu.sh
+++ b/tests/qemuxml2argvdata/qemu.sh
@@ -1,55 +1,6 @@
#! /bin/sh
-candidates="/usr/bin/qemu-kvm
- /usr/libexec/qemu-kvm
- /usr/bin/qemu-system-x86_64
- /usr/bin/qemu"
-qemu=
-for candidate in $candidates; do
- if test -x $candidate; then
- qemu=$candidate
- break
- fi
-done
-
-real_qemu()
-{
- if test x$qemu != x; then
- exec $qemu "$@"
- else
- return 1
- fi
-}
-
-faked_machine()
-{
- echo "pc"
-}
-
-faked_cpu()
-{
- cat <<EOF
-x86 Opteron_G3
-x86 Opteron_G2
-x86 Opteron_G1
-x86 Nehalem
-x86 Penryn
-x86 Conroe
-x86 [n270]
-x86 [athlon]
-x86 [pentium3]
-x86 [pentium2]
-x86 [pentium]
-x86 [486]
-x86 [coreduo]
-x86 [qemu32]
-x86 [kvm64]
-x86 [core2duo]
-x86 [phenom]
-x86 [qemu64]
-x86 [host]
-EOF
-}
+. $(dirname $0)/qemu-lib.sh
case $* in
"-M ?")
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.args
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.args
new file mode 100644
index 0000000..ac8ab1a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+./qemu-supported-cpus.sh \
+-S \
+-M pc \
+-cpu Penryn,+xtpr,+tm2,+est,+vmx,+ds_cpl,+monitor,+pbe,+tm,+ht,+ss,+acpi,+ds,+vme,-sse4.1
\
+-m 214 \
+-smp 6 \
+-nographic \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot n \
+-net none \
+-serial none \
+-parallel none \
+-usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.xml
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.xml
new file mode 100644
index 0000000..afb16f9
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.xml
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu mode='host-model'/>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/./qemu-supported-cpus.sh</emulator>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-nofallback.xml
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-nofallback.xml
new file mode 100644
index 0000000..c2ded11
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-nofallback.xml
@@ -0,0 +1,21 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu mode='host-model'>
+ <model fallback='forbid'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/./qemu-supported-cpus.sh</emulator>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.args
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.args
new file mode 100644
index 0000000..cf7eb2a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+./qemu.sh \
+-S \
+-M pc \
+-cpu core2duo,+lahf_lm,+xtpr,+cx16,+tm2,+est,+vmx,+ds_cpl,+pbe,+tm,+ht,+ss,+acpi,+ds \
+-m 214 \
+-smp 6 \
+-nographic \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot n \
+-net none \
+-serial none \
+-parallel none \
+-usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.xml
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.xml
new file mode 100644
index 0000000..96b046c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.xml
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu mode='host-model'/>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/./qemu.sh</emulator>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.args
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.args
new file mode 100644
index 0000000..c63ecce
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+./qemu.sh \
+-S \
+-M pc \
+-cpu host \
+-m 214 \
+-smp 6 \
+-nographic \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot n \
+-net none \
+-serial none \
+-parallel none \
+-usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.xml
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.xml
new file mode 100644
index 0000000..2d75025
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.xml
@@ -0,0 +1,19 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu mode='host-passthrough'/>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/./qemu.sh</emulator>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-qemu-host-passthrough.xml
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-qemu-host-passthrough.xml
new file mode 100644
index 0000000..a7123ce
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-qemu-host-passthrough.xml
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu mode='host-passthrough'/>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/./qemu.sh</emulator>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index f944d82..9e2f925 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -671,6 +671,13 @@ mymain(void)
DO_TEST("cpu-strict1", false, NONE);
DO_TEST("cpu-numa1", false, NONE);
DO_TEST("cpu-numa2", false, QEMU_CAPS_SMP_TOPOLOGY);
+ DO_TEST("cpu-host-model", false, NONE);
+ DO_TEST("cpu-host-model-fallback", false, NONE);
+ DO_TEST_FAILURE("cpu-host-model-nofallback", NONE);
+ DO_TEST("cpu-host-passthrough", false, QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST);
+ DO_TEST_FAILURE("cpu-host-passthrough", NONE);
+ DO_TEST_FAILURE("cpu-qemu-host-passthrough",
+ QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST);
DO_TEST("memtune", false, QEMU_CAPS_NAME);
DO_TEST("blkiotune", false, QEMU_CAPS_NAME);
--
1.7.8.3