This patch maps /domain/cpu/cache element into -cpu parameters:
- <cache mode='passthrough'/> is translated to host-cache-info=on
- <cache level='3' mode='emulate'/> is transformed into l3-cache=on
- <cache mode='disable'/> is turned in host-cache-info=off,l3-cache=off
Any other <cache> element is forbidden.
The tricky part is detecting whether QEMU supports the CPU properties.
The 'host-cache-info' property is introduced in v2.4.0-1389-ge265e3e480,
earlier QEMU releases enabled host-cache-info by default and had no way
to disable it. If the property is present, it defaults to 'off' for any
QEMU until at least 2.9.0.
The 'l3-cache' property was introduced later by v2.7.0-200-g14c985cffa.
Earlier versions worked as if l3-cache=off was passed. For any QEMU
until at least 2.9.0 l3-cache is 'off' by default.
QEMU 2.9.0 was the first release which supports probing both properties
by running device-list-properties with typename=host-x86_64-cpu. Older
QEMU releases did not support device-list-properties command for CPU
devices. Thus we can't really rely on probing them and we can just use
query-cpu-model-expansion QMP command as a witness.
Because the cache property probing is only reliable for QEMU >= 2.9.0
when both are already supported for quite a few releases, we let QEMU
report an error if a specific cache mode is explicitly requested. The
other mode (or both if a user requested CPU cache to be disabled) is
explicitly turned off for QEMU >= 2.9.0 to avoid any surprises in case
the QEMU defaults change. Any older QEMU already turns them off so not
doing so explicitly does not make any harm.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 8 ++++
src/qemu/qemu_capabilities.h | 2 +
src/qemu/qemu_command.c | 37 +++++++++++++++
src/qemu/qemu_domain.c | 54 ++++++++++++++++++++++
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 2 +
.../qemuxml2argv-cpu-cache-disable.args | 21 +++++++++
.../qemuxml2argv-cpu-cache-disable.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-disable2.args | 21 +++++++++
.../qemuxml2argv-cpu-cache-disable2.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-disable3.args | 22 +++++++++
.../qemuxml2argv-cpu-cache-disable3.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-emulate-l2.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-emulate-l3.args | 21 +++++++++
.../qemuxml2argv-cpu-cache-emulate-l3.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-passthrough-l3.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-passthrough.args | 21 +++++++++
.../qemuxml2argv-cpu-cache-passthrough.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-passthrough2.args | 21 +++++++++
.../qemuxml2argv-cpu-cache-passthrough2.xml | 20 ++++++++
.../qemuxml2argv-cpu-cache-passthrough3.xml | 20 ++++++++
tests/qemuxml2argvtest.c | 16 +++++++
21 files changed, 426 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index cc3e1f808..5dd18f3c5 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -364,6 +364,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"query-cpu-definitions", /* 250 */
"block-write-threshold",
"query-named-block-nodes",
+ "cpu-host-cache",
+ "cpu-l3-cache",
);
@@ -4787,6 +4789,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);
+ if (ARCH_IS_X86(qemuCaps->arch) &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_HOST_CACHE);
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_L3_CACHE);
+ }
+
ret = 0;
cleanup:
return ret;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index a7eec52a9..b4f35012f 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -401,6 +401,8 @@ typedef enum {
QEMU_CAPS_QUERY_CPU_DEFINITIONS, /* qmp query-cpu-definitions */
QEMU_CAPS_BLOCK_WRITE_THRESHOLD, /* BLOCK_WRITE_THRESHOLD event */
QEMU_CAPS_QUERY_NAMED_BLOCK_NODES, /* qmp query-named-block-nodes */
+ QEMU_CAPS_CPU_HOST_CACHE, /* host cpu supports host-cache-info property */
+ QEMU_CAPS_CPU_L3_CACHE, /* -cpu supports l3-cache property */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1116d2cd5..eb7404ead 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7063,6 +7063,43 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
have_cpu = true;
}
+ if (def->cpu && def->cpu->cache) {
+ virCPUCacheDefPtr cache = def->cpu->cache;
+ bool hostOff = false;
+ bool l3Off = false;
+
+ if (!have_cpu)
+ virBufferAdd(&buf, default_model, -1);
+
+ switch (cache->mode) {
+ case VIR_CPU_CACHE_MODE_EMULATE:
+ virBufferAddLit(&buf, ",l3-cache=on");
+ hostOff = true;
+ break;
+
+ case VIR_CPU_CACHE_MODE_PASSTHROUGH:
+ virBufferAddLit(&buf, ",host-cache-info=on");
+ l3Off = true;
+ break;
+
+ case VIR_CPU_CACHE_MODE_DISABLE:
+ hostOff = l3Off = true;
+ break;
+
+ case VIR_CPU_CACHE_MODE_LAST:
+ break;
+ }
+
+ if (hostOff &&
+ def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST_CACHE))
+ virBufferAddLit(&buf, ",host-cache-info=off");
+
+ if (l3Off &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_L3_CACHE))
+ virBufferAddLit(&buf, ",l3-cache=off");
+ }
+
if (virBufferCheckError(&buf) < 0)
goto cleanup;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 00b0b4ac4..dcce9134c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2714,6 +2714,60 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def)
if (!def->cpu)
return 0;
+ if (def->cpu->cache) {
+ virCPUCacheDefPtr cache = def->cpu->cache;
+
+ if (!ARCH_IS_X86(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU cache specification is not supported "
+ "for '%s' architecture"),
+ virArchToString(def->os.arch));
+ return -1;
+ }
+
+ switch (cache->mode) {
+ case VIR_CPU_CACHE_MODE_EMULATE:
+ if (cache->level != 3) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU cache mode '%s' can only be used with "
+ "level='3'"),
+ virCPUCacheModeTypeToString(cache->mode));
+ return -1;
+ }
+ break;
+
+ case VIR_CPU_CACHE_MODE_PASSTHROUGH:
+ if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU cache mode '%s' can only be used with "
+ "'%s' CPUs"),
+ virCPUCacheModeTypeToString(cache->mode),
+ virCPUModeTypeToString(VIR_CPU_MODE_HOST_PASSTHROUGH));
+ return -1;
+ }
+
+ if (cache->level != -1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported CPU cache level for mode '%s'"),
+ virCPUCacheModeTypeToString(cache->mode));
+ return -1;
+ }
+ break;
+
+ case VIR_CPU_CACHE_MODE_DISABLE:
+ if (cache->level != -1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported CPU cache level for mode '%s'"),
+ virCPUCacheModeTypeToString(cache->mode));
+ return -1;
+ }
+ break;
+
+ case VIR_CPU_CACHE_MODE_LAST:
+ break;
+ }
+ }
+
/* Nothing to be done if only CPU topology is specified. */
if (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
!def->cpu->model)
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
index 6386c4ed0..8e417f47b 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
@@ -207,6 +207,8 @@
<flag name='query-cpu-definitions'/>
<flag name='block-write-threshold'/>
<flag name='query-named-block-nodes'/>
+ <flag name='cpu-host-cache'/>
+ <flag name='cpu-l3-cache'/>
<version>2008090</version>
<kvmVersion>0</kvmVersion>
<package> (v2.9.0-rc0-142-g940a8ce)</package>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args
new file mode 100644
index 000000000..b4976a53c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.args
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name foo \
+-S \
+-M pc \
+-cpu host,host-cache-info=off,l3-cache=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml
new file mode 100644
index 000000000..e6f39951c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-passthrough'>
+ <cache mode='disable'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args
new file mode 100644
index 000000000..b024d8209
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.args
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name foo \
+-S \
+-M pc \
+-cpu host \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml
new file mode 100644
index 000000000..e6f39951c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable2.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-passthrough'>
+ <cache mode='disable'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args
new file mode 100644
index 000000000..19a2e9609
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.args
@@ -0,0 +1,22 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name foo \
+-S \
+-M pc \
+-cpu core2duo,+ds,+acpi,+ss,+ht,+tm,+pbe,+ds_cpl,+vmx,+est,+tm2,+cx16,+xtpr,\
++lahf_lm,l3-cache=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml
new file mode 100644
index 000000000..17078a1e8
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-disable3.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-model'>
+ <cache mode='disable'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml
new file mode 100644
index 000000000..4757e85ea
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l2.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-model' check='full'>
+ <cache level='2' mode='emulate'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args
new file mode 100644
index 000000000..31fbadaaf
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.args
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name foo \
+-S \
+-M pc \
+-cpu host,l3-cache=on,host-cache-info=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml
new file mode 100644
index 000000000..17019c673
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-emulate-l3.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-passthrough'>
+ <cache level='3' mode='emulate'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml
new file mode 100644
index 000000000..3471115ea
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough-l3.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-passthrough'>
+ <cache level='3' mode='passthrough'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args
new file mode 100644
index 000000000..fdc73b493
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.args
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name foo \
+-S \
+-M pc \
+-cpu host,host-cache-info=on,l3-cache=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml
new file mode 100644
index 000000000..74846fdd3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-passthrough'>
+ <cache mode='passthrough'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
new file mode 100644
index 000000000..cf4c55ca3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
@@ -0,0 +1,21 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name foo \
+-S \
+-M pc \
+-cpu host,host-cache-info=on \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml
new file mode 100644
index 000000000..74846fdd3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-passthrough'>
+ <cache mode='passthrough'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml
new file mode 100644
index 000000000..6ad65700b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough3.xml
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-model'>
+ <cache mode='passthrough'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index c1b014b7d..15765fdfd 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2513,6 +2513,22 @@ mymain(void)
DO_TEST("cpu-check-default-partial", QEMU_CAPS_KVM);
DO_TEST("cpu-check-default-partial2", QEMU_CAPS_KVM);
+ DO_TEST("cpu-cache-disable",
+ QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
+ DO_TEST("cpu-cache-disable2",
+ QEMU_CAPS_KVM);
+ DO_TEST("cpu-cache-disable3",
+ QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
+ DO_TEST("cpu-cache-passthrough",
+ QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
+ DO_TEST("cpu-cache-passthrough2",
+ QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE);
+ DO_TEST("cpu-cache-emulate-l3",
+ QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
+ DO_TEST_PARSE_ERROR("cpu-cache-emulate-l2", QEMU_CAPS_KVM);
+ DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM);
+ DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM);
+
qemuTestDriverFree(&driver);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
--
2.12.2
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Tue, Apr 25, 2017 at 20:48:45 +0200, Jiri Denemark wrote:
> This patch maps /domain/cpu/cache element into -cpu parameters:
>
> - <cache mode='passthrough'/> is translated to host-cache-info=on
> - <cache level='3' mode='emulate'/> is transformed into l3-cache=on
> - <cache mode='disable'/> is turned in host-cache-info=off,l3-cache=off
host-cache-info=on,l3-cache=off is specifically invalid from qemu's
point of view?
>
> Any other <cache> element is forbidden.
>
> The tricky part is detecting whether QEMU supports the CPU properties.
>
> The 'host-cache-info' property is introduced in v2.4.0-1389-ge265e3e480,
> earlier QEMU releases enabled host-cache-info by default and had no way
> to disable it. If the property is present, it defaults to 'off' for any
> QEMU until at least 2.9.0.
>
> The 'l3-cache' property was introduced later by v2.7.0-200-g14c985cffa.
> Earlier versions worked as if l3-cache=off was passed. For any QEMU
> until at least 2.9.0 l3-cache is 'off' by default.
>
> QEMU 2.9.0 was the first release which supports probing both properties
> by running device-list-properties with typename=host-x86_64-cpu. Older
> QEMU releases did not support device-list-properties command for CPU
> devices. Thus we can't really rely on probing them and we can just use
> query-cpu-model-expansion QMP command as a witness.
>
> Because the cache property probing is only reliable for QEMU >= 2.9.0
> when both are already supported for quite a few releases, we let QEMU
> report an error if a specific cache mode is explicitly requested. Thea
> other mode (or both if a user requested CPU cache to be disabled) is
> explicitly turned off for QEMU >= 2.9.0 to avoid any surprises in case
> the QEMU defaults change. Any older QEMU already turns them off so not
> doing so explicitly does not make any harm.
>
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
[...]
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index cc3e1f808..5dd18f3c5 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
[...]
> @@ -4787,6 +4789,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
> virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
> virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);
>
> + if (ARCH_IS_X86(qemuCaps->arch) &&
> + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_HOST_CACHE);
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_L3_CACHE);
Is it really necessary to add both of them separately even if you set
them both at once?
> + }
> +
> ret = 0;
> cleanup:
> return ret;
[...]
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 1116d2cd5..eb7404ead 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -7063,6 +7063,43 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
> have_cpu = true;
> }
>
> + if (def->cpu && def->cpu->cache) {
> + virCPUCacheDefPtr cache = def->cpu->cache;
> + bool hostOff = false;
> + bool l3Off = false;
> +
> + if (!have_cpu)
> + virBufferAdd(&buf, default_model, -1);
You need to set have_cpu to true after this.
> +
> + switch (cache->mode) {
> + case VIR_CPU_CACHE_MODE_EMULATE:
> + virBufferAddLit(&buf, ",l3-cache=on");
> + hostOff = true;
> + break;
> +
> + case VIR_CPU_CACHE_MODE_PASSTHROUGH:
> + virBufferAddLit(&buf, ",host-cache-info=on");
> + l3Off = true;
> + break;
> +
> + case VIR_CPU_CACHE_MODE_DISABLE:
> + hostOff = l3Off = true;
> + break;
> +
> + case VIR_CPU_CACHE_MODE_LAST:
> + break;
> + }
> +
> + if (hostOff &&
> + def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH &&
> + virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST_CACHE))
> + virBufferAddLit(&buf, ",host-cache-info=off");
> +
> + if (l3Off &&
> + virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_L3_CACHE))
> + virBufferAddLit(&buf, ",l3-cache=off");
> + }
> +
> if (virBufferCheckError(&buf) < 0)
> goto cleanup;
>
[...]
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
> new file mode 100644
> index 000000000..cf4c55ca3
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
> @@ -0,0 +1,21 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu-system-x86_64 \
> +-name foo \
> +-S \
> +-M pc \
> +-cpu host,host-cache-info=on \
This is impossible in real life since QEMU_CAPS_CPU_HOST_CACHE and
QEMU_CAPS_CPU_L3_CACHE are always defined together.
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefaults \
> +-monitor unix:/tmp/lib/domain--1-foo/monitor.sock,server,nowait \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
[...]
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index c1b014b7d..15765fdfd 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -2513,6 +2513,22 @@ mymain(void)
> DO_TEST("cpu-check-default-partial", QEMU_CAPS_KVM);
> DO_TEST("cpu-check-default-partial2", QEMU_CAPS_KVM);
>
> + DO_TEST("cpu-cache-disable",
> + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> + DO_TEST("cpu-cache-disable2",
> + QEMU_CAPS_KVM);
> + DO_TEST("cpu-cache-disable3",
> + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> + DO_TEST("cpu-cache-passthrough",
> + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> + DO_TEST("cpu-cache-passthrough2",
> + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE);
This test is misleading, you don't get a config like this with this
code.
> + DO_TEST("cpu-cache-emulate-l3",
> + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> + DO_TEST_PARSE_ERROR("cpu-cache-emulate-l2", QEMU_CAPS_KVM);
> + DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM);
> + DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM);
> +
> qemuTestDriverFree(&driver);
>
> return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
ACK with the above things sorted out.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Apr 27, 2017 at 17:09:41 +0200, Peter Krempa wrote:
> On Tue, Apr 25, 2017 at 20:48:45 +0200, Jiri Denemark wrote:
> > This patch maps /domain/cpu/cache element into -cpu parameters:
> >
> > - <cache mode='passthrough'/> is translated to host-cache-info=on
> > - <cache level='3' mode='emulate'/> is transformed into l3-cache=on
> > - <cache mode='disable'/> is turned in host-cache-info=off,l3-cache=off
>
> host-cache-info=on,l3-cache=off is specifically invalid from qemu's
> point of view?
No. Libvirt will automatically add l3-cache=off to host-cache-info=on
and host-cache-info=off to l3-cache=on if it detects QEMU supports these
properties. Otherwise it will just blindly add the one explicitly
requested and let QEMU fail if it doesn't support it.
> > Any other <cache> element is forbidden.
> >
> > The tricky part is detecting whether QEMU supports the CPU properties.
> >
> > The 'host-cache-info' property is introduced in v2.4.0-1389-ge265e3e480,
> > earlier QEMU releases enabled host-cache-info by default and had no way
> > to disable it. If the property is present, it defaults to 'off' for any
> > QEMU until at least 2.9.0.
> >
> > The 'l3-cache' property was introduced later by v2.7.0-200-g14c985cffa.
> > Earlier versions worked as if l3-cache=off was passed. For any QEMU
> > until at least 2.9.0 l3-cache is 'off' by default.
> >
> > QEMU 2.9.0 was the first release which supports probing both properties
> > by running device-list-properties with typename=host-x86_64-cpu. Older
> > QEMU releases did not support device-list-properties command for CPU
> > devices. Thus we can't really rely on probing them and we can just use
> > query-cpu-model-expansion QMP command as a witness.
> >
> > Because the cache property probing is only reliable for QEMU >= 2.9.0
> > when both are already supported for quite a few releases, we let QEMU
> > report an error if a specific cache mode is explicitly requested. Thea
> > other mode (or both if a user requested CPU cache to be disabled) is
> > explicitly turned off for QEMU >= 2.9.0 to avoid any surprises in case
> > the QEMU defaults change. Any older QEMU already turns them off so not
> > doing so explicitly does not make any harm.
> >
> > Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> > ---
>
> [...]
>
> > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> > index cc3e1f808..5dd18f3c5 100644
> > --- a/src/qemu/qemu_capabilities.c
> > +++ b/src/qemu/qemu_capabilities.c
> > @@ -4787,6 +4789,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
> > virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
> > virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);
> >
> > + if (ARCH_IS_X86(qemuCaps->arch) &&
> > + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
> > + virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_HOST_CACHE);
> > + virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_L3_CACHE);
>
> Is it really necessary to add both of them separately even if you set
> them both at once?
Hmm, I guess QEMU_CAPS_CPU_CACHE would be enough.
> > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
> > new file mode 100644
> > index 000000000..cf4c55ca3
> > --- /dev/null
> > +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-cache-passthrough2.args
> > @@ -0,0 +1,21 @@
> > +LC_ALL=C \
> > +PATH=/bin \
> > +HOME=/home/test \
> > +USER=test \
> > +LOGNAME=test \
> > +QEMU_AUDIO_DRV=none \
> > +/usr/bin/qemu-system-x86_64 \
> > +-name foo \
> > +-S \
> > +-M pc \
> > +-cpu host,host-cache-info=on \
>
> This is impossible in real life since QEMU_CAPS_CPU_HOST_CACHE and
> QEMU_CAPS_CPU_L3_CACHE are always defined together.
$cache=on is always added even if QEMU_CAPS_CPU_CACHE capability is not
set. Only the $cache=off parameters are influenced by the capability. In
other words, this is a real world command line generated for QEMU older
than 2.9.0.
> > diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> > index c1b014b7d..15765fdfd 100644
> > --- a/tests/qemuxml2argvtest.c
> > +++ b/tests/qemuxml2argvtest.c
> > @@ -2513,6 +2513,22 @@ mymain(void)
> > DO_TEST("cpu-check-default-partial", QEMU_CAPS_KVM);
> > DO_TEST("cpu-check-default-partial2", QEMU_CAPS_KVM);
> >
> > + DO_TEST("cpu-cache-disable",
> > + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> > + DO_TEST("cpu-cache-disable2",
> > + QEMU_CAPS_KVM);
> > + DO_TEST("cpu-cache-disable3",
> > + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> > + DO_TEST("cpu-cache-passthrough",
> > + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> > + DO_TEST("cpu-cache-passthrough2",
> > + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE);
>
> This test is misleading, you don't get a config like this with this
> code.
Oh right, only QEMU_CAPS_KVM should be set for this test.
>
> > + DO_TEST("cpu-cache-emulate-l3",
> > + QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST_CACHE, QEMU_CAPS_CPU_L3_CACHE);
> > + DO_TEST_PARSE_ERROR("cpu-cache-emulate-l2", QEMU_CAPS_KVM);
> > + DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM);
> > + DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM);
> > +
> > qemuTestDriverFree(&driver);
> >
> > return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
>
> ACK with the above things sorted out.
Pushed with all the things sorted out. Thanks.
Jirka
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2026 Red Hat, Inc.