6d3351
From b34dc87751a8667f22ea78730a5b678f5bd469a4 Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <b34dc87751a8667f22ea78730a5b678f5bd469a4@dist-git>
6d3351
From: Jiri Denemark <jdenemar@redhat.com>
6d3351
Date: Tue, 25 Apr 2017 19:07:19 +0200
6d3351
Subject: [PATCH] qemu: Add support for guest CPU cache
6d3351
6d3351
This patch maps /domain/cpu/cache element into -cpu parameters:
6d3351
6d3351
- <cache mode='passthrough'/> is translated to host-cache-info=on
6d3351
- <cache level='3' mode='emulate'/> is transformed into l3-cache=on
6d3351
- <cache mode='disable'/> is turned in host-cache-info=off,l3-cache=off
6d3351
6d3351
Any other <cache> element is forbidden.
6d3351
6d3351
The tricky part is detecting whether QEMU supports the CPU properties.
6d3351
6d3351
The 'host-cache-info' property is introduced in v2.4.0-1389-ge265e3e480,
6d3351
earlier QEMU releases enabled host-cache-info by default and had no way
6d3351
to disable it. If the property is present, it defaults to 'off' for any
6d3351
QEMU until at least 2.9.0.
6d3351
6d3351
The 'l3-cache' property was introduced later by v2.7.0-200-g14c985cffa.
6d3351
Earlier versions worked as if l3-cache=off was passed. For any QEMU
6d3351
until at least 2.9.0 l3-cache is 'off' by default.
6d3351
6d3351
QEMU 2.9.0 was the first release which supports probing both properties
6d3351
by running device-list-properties with typename=host-x86_64-cpu. Older
6d3351
QEMU releases did not support device-list-properties command for CPU
6d3351
devices. Thus we can't really rely on probing them and we can just use
6d3351
query-cpu-model-expansion QMP command as a witness.
6d3351
6d3351
Because the cache property probing is only reliable for QEMU >= 2.9.0
6d3351
when both are already supported for quite a few releases, we let QEMU
6d3351
report an error if a specific cache mode is explicitly requested. The
6d3351
other mode (or both if a user requested CPU cache to be disabled) is
6d3351
explicitly turned off for QEMU >= 2.9.0 to avoid any surprises in case
6d3351
the QEMU defaults change. Any older QEMU already turns them off so not
6d3351
doing so explicitly does not make any harm.
6d3351
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
(cherry picked from commit df13c0b477ffda460eed259c3b8aab7255f11199)
6d3351
6d3351
https://bugzilla.redhat.com/show_bug.cgi?id=1428952
6d3351
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
---
6d3351
 src/qemu/qemu_capabilities.c                       |  5 ++
6d3351
 src/qemu/qemu_capabilities.h                       |  1 +
6d3351
 src/qemu/qemu_command.c                            | 39 ++++++++++++++++
6d3351
 src/qemu/qemu_domain.c                             | 54 ++++++++++++++++++++++
6d3351
 tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  1 +
6d3351
 .../qemuxml2argv-cpu-cache-disable.args            | 21 +++++++++
6d3351
 .../qemuxml2argv-cpu-cache-disable.xml             | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-disable2.args           | 21 +++++++++
6d3351
 .../qemuxml2argv-cpu-cache-disable2.xml            | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-disable3.args           | 22 +++++++++
6d3351
 .../qemuxml2argv-cpu-cache-disable3.xml            | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-emulate-l2.xml          | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-emulate-l3.args         | 21 +++++++++
6d3351
 .../qemuxml2argv-cpu-cache-emulate-l3.xml          | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-passthrough-l3.xml      | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-passthrough.args        | 21 +++++++++
6d3351
 .../qemuxml2argv-cpu-cache-passthrough.xml         | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-passthrough2.args       | 21 +++++++++
6d3351
 .../qemuxml2argv-cpu-cache-passthrough2.xml        | 20 ++++++++
6d3351
 .../qemuxml2argv-cpu-cache-passthrough3.xml        | 20 ++++++++
6d3351
 tests/qemuxml2argvtest.c                           | 10 ++++
6d3351
 21 files changed, 417 insertions(+)
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml
6d3351
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml
6d3351
6d3351
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
6d3351
index 950a42bae..2c845853a 100644
6d3351
--- a/src/qemu/qemu_capabilities.c
6d3351
+++ b/src/qemu/qemu_capabilities.c
6d3351
@@ -364,6 +364,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
6d3351
               "query-cpu-definitions", /* 250 */
6d3351
               "block-write-threshold",
6d3351
               "query-named-block-nodes",
6d3351
+              "cpu-cache",
6d3351
     );
6d3351
 
6d3351
 
6d3351
@@ -4648,6 +4649,10 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
6d3351
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
6d3351
         virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);
6d3351
 
6d3351
+    if (ARCH_IS_X86(qemuCaps->arch) &&
6d3351
+        virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
6d3351
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_CACHE);
6d3351
+
6d3351
     ret = 0;
6d3351
  cleanup:
6d3351
     return ret;
6d3351
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
6d3351
index 24e2f38ee..c466a63e7 100644
6d3351
--- a/src/qemu/qemu_capabilities.h
6d3351
+++ b/src/qemu/qemu_capabilities.h
6d3351
@@ -401,6 +401,7 @@ typedef enum {
6d3351
     QEMU_CAPS_QUERY_CPU_DEFINITIONS, /* qmp query-cpu-definitions */
6d3351
     QEMU_CAPS_BLOCK_WRITE_THRESHOLD, /* BLOCK_WRITE_THRESHOLD event */
6d3351
     QEMU_CAPS_QUERY_NAMED_BLOCK_NODES, /* qmp query-named-block-nodes */
6d3351
+    QEMU_CAPS_CPU_CACHE, /* -cpu supports host-cache-info and l3-cache properties */
6d3351
 
6d3351
     QEMU_CAPS_LAST /* this must always be the last item */
6d3351
 } virQEMUCapsFlags;
6d3351
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
6d3351
index ff7f47e06..2105cde58 100644
6d3351
--- a/src/qemu/qemu_command.c
6d3351
+++ b/src/qemu/qemu_command.c
6d3351
@@ -7071,6 +7071,45 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
6d3351
         have_cpu = true;
6d3351
     }
6d3351
 
6d3351
+    if (def->cpu && def->cpu->cache) {
6d3351
+        virCPUCacheDefPtr cache = def->cpu->cache;
6d3351
+        bool hostOff = false;
6d3351
+        bool l3Off = false;
6d3351
+
6d3351
+        if (!have_cpu) {
6d3351
+            virBufferAdd(&buf, default_model, -1);
6d3351
+            have_cpu = true;
6d3351
+        }
6d3351
+
6d3351
+        switch (cache->mode) {
6d3351
+        case VIR_CPU_CACHE_MODE_EMULATE:
6d3351
+            virBufferAddLit(&buf, ",l3-cache=on");
6d3351
+            hostOff = true;
6d3351
+            break;
6d3351
+
6d3351
+        case VIR_CPU_CACHE_MODE_PASSTHROUGH:
6d3351
+            virBufferAddLit(&buf, ",host-cache-info=on");
6d3351
+            l3Off = true;
6d3351
+            break;
6d3351
+
6d3351
+        case VIR_CPU_CACHE_MODE_DISABLE:
6d3351
+            hostOff = l3Off = true;
6d3351
+            break;
6d3351
+
6d3351
+        case VIR_CPU_CACHE_MODE_LAST:
6d3351
+            break;
6d3351
+        }
6d3351
+
6d3351
+        if (hostOff &&
6d3351
+            def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH &&
6d3351
+            virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_CACHE))
6d3351
+            virBufferAddLit(&buf, ",host-cache-info=off");
6d3351
+
6d3351
+        if (l3Off &&
6d3351
+            virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_CACHE))
6d3351
+            virBufferAddLit(&buf, ",l3-cache=off");
6d3351
+    }
6d3351
+
6d3351
     if (virBufferCheckError(&buf) < 0)
6d3351
         goto cleanup;
6d3351
 
6d3351
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
6d3351
index 9c09ced0c..d31645fd1 100644
6d3351
--- a/src/qemu/qemu_domain.c
6d3351
+++ b/src/qemu/qemu_domain.c
6d3351
@@ -2688,6 +2688,60 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def)
6d3351
     if (!def->cpu)
6d3351
         return 0;
6d3351
 
6d3351
+    if (def->cpu->cache) {
6d3351
+        virCPUCacheDefPtr cache = def->cpu->cache;
6d3351
+
6d3351
+        if (!ARCH_IS_X86(def->os.arch)) {
6d3351
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6d3351
+                           _("CPU cache specification is not supported "
6d3351
+                             "for '%s' architecture"),
6d3351
+                           virArchToString(def->os.arch));
6d3351
+            return -1;
6d3351
+        }
6d3351
+
6d3351
+        switch (cache->mode) {
6d3351
+        case VIR_CPU_CACHE_MODE_EMULATE:
6d3351
+            if (cache->level != 3) {
6d3351
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6d3351
+                               _("CPU cache mode '%s' can only be used with "
6d3351
+                                 "level='3'"),
6d3351
+                               virCPUCacheModeTypeToString(cache->mode));
6d3351
+                return -1;
6d3351
+            }
6d3351
+            break;
6d3351
+
6d3351
+        case VIR_CPU_CACHE_MODE_PASSTHROUGH:
6d3351
+            if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) {
6d3351
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6d3351
+                               _("CPU cache mode '%s' can only be used with "
6d3351
+                                 "'%s' CPUs"),
6d3351
+                               virCPUCacheModeTypeToString(cache->mode),
6d3351
+                               virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH));
6d3351
+                return -1;
6d3351
+            }
6d3351
+
6d3351
+            if (cache->level != -1) {
6d3351
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6d3351
+                               _("unsupported CPU cache level for mode '%s'"),
6d3351
+                               virCPUCacheModeTypeToString(cache->mode));
6d3351
+                return -1;
6d3351
+            }
6d3351
+            break;
6d3351
+
6d3351
+        case VIR_CPU_CACHE_MODE_DISABLE:
6d3351
+            if (cache->level != -1) {
6d3351
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6d3351
+                               _("unsupported CPU cache level for mode '%s'"),
6d3351
+                               virCPUCacheModeTypeToString(cache->mode));
6d3351
+                return -1;
6d3351
+            }
6d3351
+            break;
6d3351
+
6d3351
+        case VIR_CPU_CACHE_MODE_LAST:
6d3351
+            break;
6d3351
+        }
6d3351
+    }
6d3351
+
6d3351
     /* Nothing to be done if only CPU topology is specified. */
6d3351
     if (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
6d3351
         !def->cpu->model)
6d3351
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
index 6386c4ed0..496c9ceb8 100644
6d3351
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
@@ -207,6 +207,7 @@
6d3351
   <flag name='query-cpu-definitions'/>
6d3351
   <flag name='block-write-threshold'/>
6d3351
   <flag name='query-named-block-nodes'/>
6d3351
+  <flag name='cpu-cache'/>
6d3351
   <version>2008090</version>
6d3351
   <kvmVersion>0</kvmVersion>
6d3351
   <package> (v2.9.0-rc0-142-g940a8ce)</package>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args
6d3351
new file mode 100644
6d3351
index 000000000..386e38d37
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args
6d3351
@@ -0,0 +1,21 @@
6d3351
+LC_ALL=C \
6d3351
+PATH=/bin \
6d3351
+HOME=/home/test \
6d3351
+USER=test \
6d3351
+LOGNAME=test \
6d3351
+QEMU_AUDIO_DRV=none \
6d3351
+/usr/bin/kvm \
6d3351
+-name foo \
6d3351
+-S \
6d3351
+-M pc \
6d3351
+-cpu host,host-cache-info=off,l3-cache=off \
6d3351
+-m 214 \
6d3351
+-smp 1,sockets=1,cores=1,threads=1 \
6d3351
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
6d3351
+-nographic \
6d3351
+-nodefaults \
6d3351
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
6d3351
+-no-acpi \
6d3351
+-boot c \
6d3351
+-usb \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml
6d3351
new file mode 100644
6d3351
index 000000000..e6f39951c
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-passthrough'>
6d3351
+    <cache mode='disable'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args
6d3351
new file mode 100644
6d3351
index 000000000..9348e01f8
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args
6d3351
@@ -0,0 +1,21 @@
6d3351
+LC_ALL=C \
6d3351
+PATH=/bin \
6d3351
+HOME=/home/test \
6d3351
+USER=test \
6d3351
+LOGNAME=test \
6d3351
+QEMU_AUDIO_DRV=none \
6d3351
+/usr/bin/kvm \
6d3351
+-name foo \
6d3351
+-S \
6d3351
+-M pc \
6d3351
+-cpu host \
6d3351
+-m 214 \
6d3351
+-smp 1,sockets=1,cores=1,threads=1 \
6d3351
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
6d3351
+-nographic \
6d3351
+-nodefaults \
6d3351
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
6d3351
+-no-acpi \
6d3351
+-boot c \
6d3351
+-usb \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml
6d3351
new file mode 100644
6d3351
index 000000000..e6f39951c
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-passthrough'>
6d3351
+    <cache mode='disable'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args
6d3351
new file mode 100644
6d3351
index 000000000..b882710c1
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args
6d3351
@@ -0,0 +1,22 @@
6d3351
+LC_ALL=C \
6d3351
+PATH=/bin \
6d3351
+HOME=/home/test \
6d3351
+USER=test \
6d3351
+LOGNAME=test \
6d3351
+QEMU_AUDIO_DRV=none \
6d3351
+/usr/bin/kvm \
6d3351
+-name foo \
6d3351
+-S \
6d3351
+-M pc \
6d3351
+-cpu core2duo,+ds,+acpi,+ss,+ht,+tm,+pbe,+ds_cpl,+vmx,+est,+tm2,+cx16,+xtpr,\
6d3351
++lahf_lm,l3-cache=off \
6d3351
+-m 214 \
6d3351
+-smp 1,sockets=1,cores=1,threads=1 \
6d3351
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
6d3351
+-nographic \
6d3351
+-nodefaults \
6d3351
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
6d3351
+-no-acpi \
6d3351
+-boot c \
6d3351
+-usb \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml
6d3351
new file mode 100644
6d3351
index 000000000..17078a1e8
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-model'>
6d3351
+    <cache mode='disable'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml
6d3351
new file mode 100644
6d3351
index 000000000..4757e85ea
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-model' check='full'>
6d3351
+    <cache level='2' mode='emulate'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args
6d3351
new file mode 100644
6d3351
index 000000000..c2f5d19e1
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args
6d3351
@@ -0,0 +1,21 @@
6d3351
+LC_ALL=C \
6d3351
+PATH=/bin \
6d3351
+HOME=/home/test \
6d3351
+USER=test \
6d3351
+LOGNAME=test \
6d3351
+QEMU_AUDIO_DRV=none \
6d3351
+/usr/bin/kvm \
6d3351
+-name foo \
6d3351
+-S \
6d3351
+-M pc \
6d3351
+-cpu host,l3-cache=on,host-cache-info=off \
6d3351
+-m 214 \
6d3351
+-smp 1,sockets=1,cores=1,threads=1 \
6d3351
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
6d3351
+-nographic \
6d3351
+-nodefaults \
6d3351
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
6d3351
+-no-acpi \
6d3351
+-boot c \
6d3351
+-usb \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml
6d3351
new file mode 100644
6d3351
index 000000000..17019c673
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-passthrough'>
6d3351
+    <cache level='3' mode='emulate'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml
6d3351
new file mode 100644
6d3351
index 000000000..3471115ea
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-passthrough'>
6d3351
+    <cache level='3' mode='passthrough'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args
6d3351
new file mode 100644
6d3351
index 000000000..1d824f6dd
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args
6d3351
@@ -0,0 +1,21 @@
6d3351
+LC_ALL=C \
6d3351
+PATH=/bin \
6d3351
+HOME=/home/test \
6d3351
+USER=test \
6d3351
+LOGNAME=test \
6d3351
+QEMU_AUDIO_DRV=none \
6d3351
+/usr/bin/kvm \
6d3351
+-name foo \
6d3351
+-S \
6d3351
+-M pc \
6d3351
+-cpu host,host-cache-info=on,l3-cache=off \
6d3351
+-m 214 \
6d3351
+-smp 1,sockets=1,cores=1,threads=1 \
6d3351
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
6d3351
+-nographic \
6d3351
+-nodefaults \
6d3351
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
6d3351
+-no-acpi \
6d3351
+-boot c \
6d3351
+-usb \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml
6d3351
new file mode 100644
6d3351
index 000000000..74846fdd3
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-passthrough'>
6d3351
+    <cache mode='passthrough'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
6d3351
new file mode 100644
6d3351
index 000000000..d7863ba2e
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
6d3351
@@ -0,0 +1,21 @@
6d3351
+LC_ALL=C \
6d3351
+PATH=/bin \
6d3351
+HOME=/home/test \
6d3351
+USER=test \
6d3351
+LOGNAME=test \
6d3351
+QEMU_AUDIO_DRV=none \
6d3351
+/usr/bin/kvm \
6d3351
+-name foo \
6d3351
+-S \
6d3351
+-M pc \
6d3351
+-cpu host,host-cache-info=on \
6d3351
+-m 214 \
6d3351
+-smp 1,sockets=1,cores=1,threads=1 \
6d3351
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
6d3351
+-nographic \
6d3351
+-nodefaults \
6d3351
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
6d3351
+-no-acpi \
6d3351
+-boot c \
6d3351
+-usb \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml
6d3351
new file mode 100644
6d3351
index 000000000..74846fdd3
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-passthrough'>
6d3351
+    <cache mode='passthrough'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml
6d3351
new file mode 100644
6d3351
index 000000000..6ad65700b
6d3351
--- /dev/null
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml
6d3351
@@ -0,0 +1,20 @@
6d3351
+<domain type='kvm'>
6d3351
+  <name>foo</name>
6d3351
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
6d3351
+  <memory unit='KiB'>219136</memory>
6d3351
+  <currentMemory unit='KiB'>219136</currentMemory>
6d3351
+  <vcpu placement='static'>1</vcpu>
6d3351
+  <os>
6d3351
+    <type arch='x86_64' machine='pc'>hvm</type>
6d3351
+    <boot dev='hd'/>
6d3351
+  </os>
6d3351
+  <cpu mode='host-model'>
6d3351
+    <cache mode='passthrough'/>
6d3351
+  </cpu>
6d3351
+  <clock offset='utc'/>
6d3351
+  <on_poweroff>destroy</on_poweroff>
6d3351
+  <on_reboot>restart</on_reboot>
6d3351
+  <on_crash>destroy</on_crash>
6d3351
+  <devices>
6d3351
+  </devices>
6d3351
+</domain>
6d3351
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
6d3351
index 94be771d3..81cd2a6ec 100644
6d3351
--- a/tests/qemuxml2argvtest.c
6d3351
+++ b/tests/qemuxml2argvtest.c
6d3351
@@ -2521,6 +2521,16 @@ mymain(void)
6d3351
     DO_TEST("cpu-check-default-partial", QEMU_CAPS_KVM);
6d3351
     DO_TEST("cpu-check-default-partial2", QEMU_CAPS_KVM);
6d3351
 
6d3351
+    DO_TEST("cpu-cache-disable", QEMU_CAPS_KVM, QEMU_CAPS_CPU_CACHE);
6d3351
+    DO_TEST("cpu-cache-disable2", QEMU_CAPS_KVM);
6d3351
+    DO_TEST("cpu-cache-disable3", QEMU_CAPS_KVM, QEMU_CAPS_CPU_CACHE);
6d3351
+    DO_TEST("cpu-cache-passthrough", QEMU_CAPS_KVM, QEMU_CAPS_CPU_CACHE);
6d3351
+    DO_TEST("cpu-cache-passthrough2", QEMU_CAPS_KVM);
6d3351
+    DO_TEST("cpu-cache-emulate-l3", QEMU_CAPS_KVM, QEMU_CAPS_CPU_CACHE);
6d3351
+    DO_TEST_PARSE_ERROR("cpu-cache-emulate-l2", QEMU_CAPS_KVM);
6d3351
+    DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM);
6d3351
+    DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM);
6d3351
+
6d3351
     qemuTestDriverFree(&driver);
6d3351
 
6d3351
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
6d3351
-- 
6d3351
2.12.2
6d3351